In A.h I have the following class
class A
{
int a;
char name[100];
}
B.h has the following code
class A;
Class B
{
public:
int c;
float d;
getObjectDetails(A *);
};
I compiled it as g++ A.h B.h B.cpp -o out
. But it gives compilation errors saying class A is incomplete. Could any one please help me understand?
Also, if I include header file A.h in B.h, everything goes fine. In that case, I开发者_开发问答 need not declare Class A before Class B definition I think, I can directly create and use instance of class A. Could anyone clarify me on this point?
what happens in step "class A" declaration at compile time and run time?
You can only use forward declarations with pointers and references (because these are of a fixed size, independent of the size of the object they refer to). If you use a specific class by value, the compiler needs its full definition (in order to know its exact size), thus forward declaration is not enough.
You can only use forward declarations for type identification, such as when you use the declared type in a function/method pointer parameter prototype. If you are going to declare a member variable (i.e. std::string _name;) the compiler needs a little bit more than a forward declaration can give it. For example, if someone does a sizeof(Student) the compiler has to have access to the entire declaration to figure out the size.
Answer by Péter Török from this thread.
It should compile fine, if you
1) add a semi-colon at the end of class A declaration.
2) change "C" to "c" in class B declaration.
3) add a return type to getObjectDetails()
The problem is surely in B.cpp, because B.h is fine. If you are trying to do anything with the A*
received by getObjectDetails()
(such as calling a method on it), the compiler will not be able to understand it.
To fix it, try including A.h in B.cpp (B.h does not need it, indeed).
You probably don't have #include "A.h"
in B.cpp
, which is then using A in such a way that it requires A to be defined, not just declared. Absent the definition, just about the only thing you can do with the A*
passed to getObjectDetails
is store it in an A*
or void*
variable, or pass it on to some other code outside B.cpp
.
You should #include A.h from B.h. What you've done instead is called a forward declaration, and is only recommended when A.h either contains an enormous amount of code, or includes other files that do. Then, the "class A;" thing can be a quick way to let your compiler know that A is a class, and hence accept pointers and reference to A objects, without parsing all the extra code from A.h. Your A.h is not long enough to justify such a hack. It is much better to directly use the authoratative source of information about A, which is A.h, instead of spreading information about A (which may one day cease to be true) throughout B. I actively dislike this forward declaration hack, and recommend creating a dedicated forward declaration header that contains "class A;" and any other classes A.h grows to contain, so that uses like B can include that if they don't need the full declarations. This is done by the Standard Library in , which forward declares useful classes, variables and constants for the heavier-weight .
Then, your B.cpp should #include B.h. Your command line should simply be:
g++ B.cpp -o out
(no need to mention A.h or B.h as they will be included (indirectly and directly respectively) from B.cpp.
This code
class A;
class B
{
public:
int c;
float d;
void getObjectDetails(A *);
};
compiles fine for me using VC9 (VS 2008) and I believe this to be correct.
If your code does not compile, it differs from the above in a significant detail. The only way for you to find that (there's no way for us to find it) is to take (a copy of) your original code, and start removing things step by step until the error goes away.
Either you then understand what the problem is or you end up with <20 lines of self-contained example code which reproduce the error - a perfect repro to come back here and ask about.
精彩评论