如何在C++中使用循环依赖类



此代码未编译。

我可以做什么修改来达到期望的结果?

ClassOne.h

#ifndef _CLASS_ONE_
#define _CLASS_ONE_
#include <string>
#include "ClassTwo.h"
class ClassTwo;
class ClassOne
{
private:
    string message;     
    friend ClassTwo;
    ClassTwo m_ClassTwo;
public:
    ClassOne();
    void Display();
};
#endif

ClassTwo.h

#ifndef _CLASS_TWO_
#define _CLASS_TWO_
#include <string>
#include "ClassOne.h"
class ClassOne;
class ClassTwo
{
private:
    string message;
    friend ClassOne;
    ClassOne m_ClassOne;
public:
    ClassTwo();
    void Display();
};
#endif

ClassOne.cpp

#include "ClassOne.h"
#include "ClassTwo.h"
#include <iostream>
ClassOne :: ClassOne()
{
    std::cout<<"ClassOne()...calledn";
    this->m_ClassTwo.message = "ClassOne - Messagen";
}
void ClassOne :: Display()
{
    std::cout<<this->m_ClassTwo.message;
}

ClassTwo.cpp

#include "ClassTwo.h"
#include "ClassOne.h"
#include <iostream>
ClassTwo :: ClassTwo()
{
    std::cout<<"ClassTwo()...calledn";
    this->m_ClassOne.message = "ClassTwo - Messagen";
}
void ClassTwo :: Display()
{
    std::cout<<this->m_ClassOne.message;
}

main.cpp

#include "ClassOne.h"
#include "ClassTwo.h"
int main()
{
    ClassOne one;
    one.Display();
    ClassTwo two;
    two.Display();
}

错误消息

1   error C2146: syntax error : missing ';' before identifier 'message'
2   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
3   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
4   error C2079: 'ClassTwo::m_ClassOne' uses undefined class 'ClassOne'
5   error C2146: syntax error : missing ';' before identifier 'message'
6   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
7   error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
8   error C2039: 'message' : is not a member of 'ClassTwo'
9   error C2039: 'message' : is not a member of 'ClassTwo'
10  error C2146: syntax error : missing ';' before identifier 'message'
11  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
12  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
13  error C2079: 'ClassOne::m_ClassTwo' uses undefined class 'ClassTwo'
14  error C2146: syntax error : missing ';' before identifier 'message'
15  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
16  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
17  error C2039: 'message' : is not a member of 'ClassOne'
18  error C2039: 'message' : is not a member of 'ClassOne'
19  error C2146: syntax error : missing ';' before identifier 'message'
20  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
21  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
22  error C2079: 'ClassTwo::m_ClassOne' uses undefined class 'ClassOne'
23  error C2146: syntax error : missing ';' before identifier 'message'
24  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
25  error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

您永远无法编译该代码。您已经描述了一个系统,其中类型a包含类型B,类型B包含类型a。因此,类型a和B都递归且无限地包含它们自己,这是不可能的。您必须从根本上重新设计代码以消除这个问题。

此外,您的friend语法错误。

如上所述,您需要转发声明ClassOne或ClassTwo中的至少一个。

因此,你ClassOne.h可以看起来像:

#ifndef _CLASS_ONE_
#define _CLASS_ONE_
#include <string>
class ClassTwo;
class ClassOne
{
private:
    string message;
    ClassTwo* m_ClassTwo;
public:
    ClassOne();
    void Display();
};
#endif

正如你所看到的,我们声明了ClassTwo,但不包括它。我们基本上只告诉编译器,是的,我们确实有一个ClassTwo。但我们现在并不关心它包含什么。

另请查看您的ClassTwo成员,这现在是一个指针。原因是一个成员需要编译器知道对象的大小,而我们目前不知道它是什么。因此,你需要一个指针或一个参考

接下来,在ClassOne.cpp中,需要包含ClassTwo.h,以获取该类的函数和大小。

不过有几件事:对于不能从ClassTwo继承的正向声明,请在头文件中使用转发类的方法(编译器如何知道存在哪些方法?)使用转发类定义函数或方法,即必须通过引用传递或传递指针。

1)使用前向声明:

添加

class ClassTwo;

至ClassOne.h

class ClassTwo;

至ClassTwo.h

2) 您需要使用运算符new动态创建成员变量(或至少创建其中一个),或者如果您愿意,使用其中一个智能指针,如boost库中的boost::shared_ptr或标准库中的std::shared_ptr(如果您使用C++11)。

最新更新