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

时间:2012-02-27 07:45:47

标签: c++ class cross-reference

此代码未编译。

我可以做些什么修改来达到预期效果?

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()...called\n";
    this->m_ClassTwo.message = "ClassOne - Message\n";
}

void ClassOne :: Display()
{
    std::cout<<this->m_ClassTwo.message;
}

ClassTwo.cpp

#include "ClassTwo.h"
#include "ClassOne.h"
#include <iostream>

ClassTwo :: ClassTwo()
{
    std::cout<<"ClassTwo()...called\n";
    this->m_ClassOne.message = "ClassTwo - Message\n";
}

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

3 个答案:

答案 0 :(得分:6)

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

此外,您的friend语法错误。

答案 1 :(得分:3)

如上所述,您需要转发至少声明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,在头文件中使用转发类的方法(编译器如何知道哪些方法存在?)使用转发类定义函数或方法,即你必须通过引用传递或传递指针。

答案 2 :(得分:1)

1)使用前向声明:

添加

class ClassTwo;

到ClassOne.h

class ClassTwo;

到ClassTwo.h

2)您需要使用operator new或者如果您愿意,使用其中一个智能指针(如来自boost库的boost::shared_ptr或{}来动态创建成员变量(或至少其中一个)如果您使用C ++ 11,则从标准库中{1}}。