C++中的相互类实例

sep*_*oad 4 c++ pointers class

这段代码有什么问题?这里我们有两个文件:classA.h和classB.h

classA.h:

#ifndef _class_a_h_
#define _class_a_h_

#include "classB.h"

class B; //????

class A
{
public:
    A() {
        ptr_b = new B(); //????
    }

    virtual ~A() {
        if(ptr_b) delete ptr_b; //????
                    num_a = 0;
    }

    int num_a;
    B* ptr_b; //????
};

#endif //_class_a_h_
Run Code Online (Sandbox Code Playgroud)

classB.h:

#ifndef _class_b_h_
#define _class_b_h_

#include "classA.h"

class A; //????

class B
{
public:     
    B() { 
        ptr_a = new A(); //????
                    num_b = 0;
    }

    virtual ~B() { 
        if(ptr_a) delete ptr_a; //????
    }

    int num_b;
    A* ptr_a; //????
};

#endif //_class_b_h_
Run Code Online (Sandbox Code Playgroud)

当我尝试编译它时,编译器(g ++)说:

classB.h:在构造函数'B :: B()'中:

classB.h:12:错误:无效使用不完整类型'struct A'

classB.h:6:错误:'struct A'的前向声明

classB.h:在析构函数'virtual B :: ~B()'中:

classB.h:16:警告:在调用delete运算符时检测到可能的问题:

classB.h:16:警告:无效使用不完整类型'struct A'

classB.h:6:警告:'struct A'的前向声明

classB.h:16:注意:析构函数和类特定的运算符delete都不会

调用,即使它们是在定义类时声明的.

Jam*_*lis 9

您无法创建不完整类型的实例(编译器对该类一无所知!)

您需要将函数的定义(A和B的构造函数)移动到一个C++文件中,该文件可以包含两个头文件(如果您遵循每个文件有一个类的约定,则可以包含在多个C++文件中).

话虽如此,你写的代码有一个严重的问题:每个A创建一个B的实例,每个B创建和A的实例.你将最终得到一个无限递归,你最终会耗尽内存.

两个次要的挑剔:你不需要在调用delete之前测试指针是否为空(删除空指针是安全的),并且你需要更改你的包含保护(在全局命名空间中以下划线开头的名称是保留给实施).