简体   繁体   中英

C++ How is this an Incomplete Type?

Here is the code

#include <iostream>

#include "ClassA.h"

ClassA* class_a = new ClassA();

int main() {



    return 0;
}

Class A

#ifndef CLASSA_H
#define CLASSA_H

#include <iostream>
#include "ClassB.h"

class ClassA
{
public:
    ClassA()
    {
        ClassB classB = new ClassB();

        std::cout << "End of constructor" << std::endl;
    }

    void ClassA::DoSomething( void )
    {
        std::cout << "ClassA  DoSomething";
    }
};


#endif  /* CLASSA_H */

Class B

#ifndef CLASSB_H
#define CLASSB_H

class ClassA;

extern ClassA* class_a;

class ClassB
{

public:

    ClassB ()
    {
        ::class_a->DoSomething();
        std::cout << "ClassB constructor" << std::endl;
    }

};


#endif  /* CLASSB_H */

In ClassB 's constructor I get a compile error at ::class_a->DoSomething(); saying member access into incomplete type "ClassA" . But how is ClassA incomplete when it is parsing ClassB's constructor? When it is going through ClassA, does it get to the type ClassB in it's constructor and then hope over to that file?

It's an incomplete type because you have not included the header for ClassA in the ClassB header but you're trying to use the ClassA instance. In other words, the compiler knows there is a ClassA thanks to the forward declaration, which is sufficient to declare a pointer, but the type is incomplete and cannot be used because the compiler hasn't seen the declaration of the type.

You need to make a source file (eg, ClassB.cpp ), include the ClassA header in the source file, and move the ClassB constructor's implementation to the source file.

Let's look at this from the point of the compile after it has processed the includes:

#line 1 main.cpp
//#include <iostream>
/* Text of iostream inserted here */
//#include "ClassA.h"
#line 1 ClassA.h

//#ifndef CLASSA_H (it isn't defined)
#define CLASSA_H

//#include <iostream>
/* Almost nothing here because iostream has already been included */

//#include "ClassB.h"
#line 1 ClassB.h
//#ifndef CLASSB_H (again, it isn't defined)
#define CLASSB_H

class ClassA;

extern ClassA* class_a;

class ClassB
{

public:

    ClassB ()
    {
        ::class_a->DoSomething();

Right. So we compiled main.cpp, which included ClassA.h which included ClassB.h. At the point we have got to here, ClassA is not defined.

Move (at least) one of the constructors into a separate .cpp file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM