forward declaration with vector of class type - pointer to incomplete class type not allowed
up vote
9
down vote
favorite
I have two classes, foo
and bar
.
foo.h #include
s bar.h and contains a std::vector
of pointers to bar
objects. At some point during runtime, bar
has to access this vector of pointers to other bar
objects. Therefore, foo
contains a method named getBarObjects()
that returns the array of pointers.
Therefore, I forward declare foo
in bar.h. I obviously also have to forward declare the method I'm using - foo::getBarObjects()
. As this returns the array of pointers to bar
, I get into a vicious cycle.
I cannot forward declare Bar and then simply forward declare getBarObjects()
, as this results in "incomplete type name is not allowed".
foo.h:
#include "bar.h"
#include <vector>
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
}
bar.h:
class foo;
std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp:
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
}
If I simply include the other way around, I'll have just the same problem in foo
later on. Any suggestions?
c++ circular-dependency forward-declaration
add a comment |
up vote
9
down vote
favorite
I have two classes, foo
and bar
.
foo.h #include
s bar.h and contains a std::vector
of pointers to bar
objects. At some point during runtime, bar
has to access this vector of pointers to other bar
objects. Therefore, foo
contains a method named getBarObjects()
that returns the array of pointers.
Therefore, I forward declare foo
in bar.h. I obviously also have to forward declare the method I'm using - foo::getBarObjects()
. As this returns the array of pointers to bar
, I get into a vicious cycle.
I cannot forward declare Bar and then simply forward declare getBarObjects()
, as this results in "incomplete type name is not allowed".
foo.h:
#include "bar.h"
#include <vector>
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
}
bar.h:
class foo;
std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp:
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
}
If I simply include the other way around, I'll have just the same problem in foo
later on. Any suggestions?
c++ circular-dependency forward-declaration
add a comment |
up vote
9
down vote
favorite
up vote
9
down vote
favorite
I have two classes, foo
and bar
.
foo.h #include
s bar.h and contains a std::vector
of pointers to bar
objects. At some point during runtime, bar
has to access this vector of pointers to other bar
objects. Therefore, foo
contains a method named getBarObjects()
that returns the array of pointers.
Therefore, I forward declare foo
in bar.h. I obviously also have to forward declare the method I'm using - foo::getBarObjects()
. As this returns the array of pointers to bar
, I get into a vicious cycle.
I cannot forward declare Bar and then simply forward declare getBarObjects()
, as this results in "incomplete type name is not allowed".
foo.h:
#include "bar.h"
#include <vector>
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
}
bar.h:
class foo;
std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp:
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
}
If I simply include the other way around, I'll have just the same problem in foo
later on. Any suggestions?
c++ circular-dependency forward-declaration
I have two classes, foo
and bar
.
foo.h #include
s bar.h and contains a std::vector
of pointers to bar
objects. At some point during runtime, bar
has to access this vector of pointers to other bar
objects. Therefore, foo
contains a method named getBarObjects()
that returns the array of pointers.
Therefore, I forward declare foo
in bar.h. I obviously also have to forward declare the method I'm using - foo::getBarObjects()
. As this returns the array of pointers to bar
, I get into a vicious cycle.
I cannot forward declare Bar and then simply forward declare getBarObjects()
, as this results in "incomplete type name is not allowed".
foo.h:
#include "bar.h"
#include <vector>
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
}
bar.h:
class foo;
std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp:
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
}
If I simply include the other way around, I'll have just the same problem in foo
later on. Any suggestions?
c++ circular-dependency forward-declaration
c++ circular-dependency forward-declaration
edited Nov 20 at 17:13
Fabio Turati
2,54752138
2,54752138
asked Oct 10 '11 at 14:35
Aerius
349418
349418
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
up vote
19
down vote
accepted
You can't forward declare members.
Instead, bar.cpp
should #include
both foo.h
and bar.h
. Problem solved.
In general, if you use the sequence:
- Forward declare all class types
- Define all class types
- Bodies of class members
everything will be fine.
Meh, simple solution to a problem that seemed big. Thank you!
– Aerius
Oct 10 '11 at 15:14
I have been looking for this solution for hours. Thank you!
– tcallred
Aug 17 at 4:13
add a comment |
up vote
6
down vote
You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.
foo.h
#include <vector>
class bar;
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
};
bar.h
class foo;
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp
#include "foo.h"
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects();
}
add a comment |
up vote
1
down vote
You forgot to forward declare the vector in foo.h. You also return the vector
by-value from getBarObjects
which is possibly not what you want and the forward declaration of the member function is useless.
Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr
, unique_ptr
) over raw pointers. Watch out for const
ness.
I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
– Aerius
Oct 10 '11 at 14:40
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7714345%2fforward-declaration-with-vector-of-class-type-pointer-to-incomplete-class-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
19
down vote
accepted
You can't forward declare members.
Instead, bar.cpp
should #include
both foo.h
and bar.h
. Problem solved.
In general, if you use the sequence:
- Forward declare all class types
- Define all class types
- Bodies of class members
everything will be fine.
Meh, simple solution to a problem that seemed big. Thank you!
– Aerius
Oct 10 '11 at 15:14
I have been looking for this solution for hours. Thank you!
– tcallred
Aug 17 at 4:13
add a comment |
up vote
19
down vote
accepted
You can't forward declare members.
Instead, bar.cpp
should #include
both foo.h
and bar.h
. Problem solved.
In general, if you use the sequence:
- Forward declare all class types
- Define all class types
- Bodies of class members
everything will be fine.
Meh, simple solution to a problem that seemed big. Thank you!
– Aerius
Oct 10 '11 at 15:14
I have been looking for this solution for hours. Thank you!
– tcallred
Aug 17 at 4:13
add a comment |
up vote
19
down vote
accepted
up vote
19
down vote
accepted
You can't forward declare members.
Instead, bar.cpp
should #include
both foo.h
and bar.h
. Problem solved.
In general, if you use the sequence:
- Forward declare all class types
- Define all class types
- Bodies of class members
everything will be fine.
You can't forward declare members.
Instead, bar.cpp
should #include
both foo.h
and bar.h
. Problem solved.
In general, if you use the sequence:
- Forward declare all class types
- Define all class types
- Bodies of class members
everything will be fine.
answered Oct 10 '11 at 14:37
Ben Voigt
233k29308563
233k29308563
Meh, simple solution to a problem that seemed big. Thank you!
– Aerius
Oct 10 '11 at 15:14
I have been looking for this solution for hours. Thank you!
– tcallred
Aug 17 at 4:13
add a comment |
Meh, simple solution to a problem that seemed big. Thank you!
– Aerius
Oct 10 '11 at 15:14
I have been looking for this solution for hours. Thank you!
– tcallred
Aug 17 at 4:13
Meh, simple solution to a problem that seemed big. Thank you!
– Aerius
Oct 10 '11 at 15:14
Meh, simple solution to a problem that seemed big. Thank you!
– Aerius
Oct 10 '11 at 15:14
I have been looking for this solution for hours. Thank you!
– tcallred
Aug 17 at 4:13
I have been looking for this solution for hours. Thank you!
– tcallred
Aug 17 at 4:13
add a comment |
up vote
6
down vote
You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.
foo.h
#include <vector>
class bar;
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
};
bar.h
class foo;
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp
#include "foo.h"
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects();
}
add a comment |
up vote
6
down vote
You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.
foo.h
#include <vector>
class bar;
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
};
bar.h
class foo;
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp
#include "foo.h"
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects();
}
add a comment |
up vote
6
down vote
up vote
6
down vote
You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.
foo.h
#include <vector>
class bar;
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
};
bar.h
class foo;
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp
#include "foo.h"
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects();
}
You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.
foo.h
#include <vector>
class bar;
class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
};
bar.h
class foo;
class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}
bar.cpp
#include "foo.h"
#include "bar.h"
bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}
bool bar::dosth() {
thisFoo->getBarObjects();
}
answered Oct 10 '11 at 14:51
CurtisB
1945
1945
add a comment |
add a comment |
up vote
1
down vote
You forgot to forward declare the vector in foo.h. You also return the vector
by-value from getBarObjects
which is possibly not what you want and the forward declaration of the member function is useless.
Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr
, unique_ptr
) over raw pointers. Watch out for const
ness.
I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
– Aerius
Oct 10 '11 at 14:40
add a comment |
up vote
1
down vote
You forgot to forward declare the vector in foo.h. You also return the vector
by-value from getBarObjects
which is possibly not what you want and the forward declaration of the member function is useless.
Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr
, unique_ptr
) over raw pointers. Watch out for const
ness.
I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
– Aerius
Oct 10 '11 at 14:40
add a comment |
up vote
1
down vote
up vote
1
down vote
You forgot to forward declare the vector in foo.h. You also return the vector
by-value from getBarObjects
which is possibly not what you want and the forward declaration of the member function is useless.
Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr
, unique_ptr
) over raw pointers. Watch out for const
ness.
You forgot to forward declare the vector in foo.h. You also return the vector
by-value from getBarObjects
which is possibly not what you want and the forward declaration of the member function is useless.
Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr
, unique_ptr
) over raw pointers. Watch out for const
ness.
edited Apr 11 '15 at 14:21
answered Oct 10 '11 at 14:37
pmr
46.3k686137
46.3k686137
I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
– Aerius
Oct 10 '11 at 14:40
add a comment |
I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
– Aerius
Oct 10 '11 at 14:40
I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
– Aerius
Oct 10 '11 at 14:40
I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
– Aerius
Oct 10 '11 at 14:40
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7714345%2fforward-declaration-with-vector-of-class-type-pointer-to-incomplete-class-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown