在C ++中处理共同依赖类的最佳方法是什么?

时间:2010-01-27 00:18:26

标签: c++ header

假设我有一个类foo,类bar的对象是成员

class foo
{
    bar m_bar;
};

现在假设酒吧需​​要跟踪拥有它的foo

class bar
{
    foo * m_pfoo;
}

这两个类相互引用而没有前向声明,不会编译。因此,在foo声明之前添加此行可以解决该问题

class bar;

现在,问题是 - 在编写头文件时,每个依赖于另一个:foo.h需要bar.h中的定义,反之亦然。处理这个问题的正确方法是什么?

4 个答案:

答案 0 :(得分:24)

您需要将所有成员访问权限从标题中移出,并放入源文件中。

这样,您可以在标头中转发声明您的类,并在foo中定义它们:

// foo.h
class bar;

class foo {
    bar * m_pbar;
}

// bar.h
class foo;
class bar {
    foo * parent;
}

这将允许您工作 - 您只是不能将需要成员信息的定义放入标题 - 将其移动到.cpp文件。 .cpp文件可以包含foo.h和bar.h:

// Foo.cpp
#include "foo.h"
#Include "bar.h"

void foo::some_method() {
     this->m_pbar->do_something(); // Legal, now, since both headers have been included
}

答案 1 :(得分:2)

我想一种方法是创建没有成员的抽象接口类。然后从这些接口类中继承foo和bar。

e.g:

class FooInterface
{
   // methods here
}

class BarInterface
{
   // methods here
}

class Foo : public FooInterface
{
   BarInterface *pBar;
}

class Bar : public BarInterface
{
   FooInterface *pFoo;
}

这打破了依赖关系的循环(除非接口本身彼此依赖,如果是这种情况,那么它们应该在同一个文件中声明)

答案 2 :(得分:1)

在您的示例中,foo取决于bar(因为它包含实际的bar对象),但bar不依赖于foo(从它只包含foo *)。现在bar确实依赖于foo作为类型名称,因此bar.h需要名称的前向声明:class foo;foo取决于bar,因此foo.h应包含#include "bar.h"

你不能在C ++中拥有直接相互依赖的类;它根本不起作用。您需要将类分离,以便仅依赖于其他类,例如在您的示例中。唯一产生直接依赖的东西是使用类作为基类或字段;任何其他用途只会产生间接依赖,这通常不是问题。

答案 3 :(得分:0)

据我所知,唯一真正的方法是使用指针,因为它们不需要类定义,直到翻译单元(.cpp),在这种情况下两个类都将被正确定义。