【问题标题】:C++ How is this an Incomplete Type?C++ 这是一个不完整的类型吗?
【发布时间】:2016-06-07 22:16:56
【问题描述】:

这里是代码

#include <iostream>

#include "ClassA.h"

ClassA* class_a = new ClassA();

int main() {



    return 0;
}

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 */

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 */

ClassB 的构造函数中,我在::class_a-&gt;DoSomething(); 得到一个编译错误member access into incomplete type "ClassA"。但是ClassA在解析ClassB的构造函数时怎么不完整呢?当它通过 ClassA 时,它是否会在其构造函数中到达 ClassB 类型,然后希望转到该文件?

【问题讨论】:

  • 编译器并没有试图欺骗你。 ClassA 在解析class_a-&gt;DoSomething(); 行时确实没有定义。尝试将 .h 文件的内容放在一个 .cc 文件中,然后检查 .cc 文件的内容。
  • 这很明显。 BA 的定义在哪里?您只有一个前向声明,因此除了存储引用(指针或引用)之外,您不能做任何事情。

标签: c++ incomplete-type


【解决方案1】:

这是一个不完整的类型,因为您没有在 ClassB 标头中包含 ClassA 的标头 但您正在尝试使用 ClassA 实例。 换句话说,编译器由于前向声明知道有ClassA,这足以声明一个指针,但是类型不完整,无法使用,因为编译器没有看到类型的声明。

您需要制作一个源文件(例如ClassB.cpp),在源文件中包含ClassA 标头,并将ClassB 构造函数的实现移动到源文件中。

【讨论】:

    【解决方案2】:

    在处理完包含后,让我们从编译的角度来看:

    #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();
    

    没错。所以我们编译了main.cpp,其中包含了ClassA.h,其中包含了ClassB.h。至此,ClassA 尚未定义。

    将(至少)其中一个构造函数移动到单独的 .cpp 文件中。

    【讨论】:

    • 所以编译器在继续下一个文件之前不能完全通过一个文件?它跟随#include ... 去哪里?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-06
    • 2012-10-13
    • 2013-09-15
    • 2012-11-18
    • 2016-12-07
    • 2017-01-08
    相关资源
    最近更新 更多