C++中继承的循环依赖

Circular dependency on inheritance in C++

我已经在网上搜索了很多,但我还没有找到任何可以解决我的问题的东西。我有这些 classes:

文件:A.h

#include "B.h"

class A {
...
B method();
}

文件:B.h

#include "A.h"

class B : public A {
...
}

我在 B class 文件中收到此错误 "expected class-name before ‘{’ token"。我试过在 A.h 和 B.h 中添加 class 声明,但没有任何效果。我猜这是一个循环依赖问题。有人能帮帮我吗?

这叫做"forward declaration"。例如:

#include "B.h"

class B;

class A {
...
B method();
};

只要声明方法,不实际定义,就可以声明方法。

实际的 C 文件将包含两个 header 文件,并且具有两个 class 的定义,现在可以定义、调用和使用 class 方法。

您可能想要开始查看标准 C++ header,例如 <iostream><string> 等。 C++ 库中的所有模板通常相互之间具有复杂的相互依赖性。

您可能会发现您的 C++ 编译器已按照相当严格的顺序构建其 header。首先是所有前向声明和 class 声明。只有在声明所有内容之后,您才会看到实际的模板声明。

这几乎是唯一可行的方法。

以下适合我。如果您仍然遇到问题,您应该提供 mvce.

Foo.h

#ifndef FOO_H
#define FOO_H

class Bar; // Forward declaration

// Note: I'm not sure why this interface knows anything about the derived type
class Foo
{
public:
    // Omitted the virtual destructor in this example

    Bar& try1();
    const Bar& try2() const;

    Bar try3() const;

    Bar* try4();
    const Bar* try5() const;
};

#endif

Foo.cpp

#include "Foo.h"

#include "Bar.h"

Bar& Foo::try1()
{
    return static_cast<Bar&>(*this);
}

const Bar& Foo::try2() const
{
    return static_cast<const Bar&>(*this);
}

Bar Foo::try3() const
{
    return Bar();
}

Bar* Foo::try4()
{
    return static_cast<Bar*>(this);
}

const Bar* Foo::try5() const
{
    return static_cast<const Bar*>(this);
}

Bar.h

#ifndef BAR_H
#define BAR_H

#include "Foo.h"

class Bar : public Foo
{
};

#endif

main.cpp

#include "Foo.h"
#include "Bar.h"

int main()
{
    Foo f;
    f.try1();
    f.try2();
    f.try3();
    f.try4();
    f.try5();

    return 0;
}

您的问题有多种解决方案,但最好的解决方案是根据您的 classes(我们对此一无所知)的设计量身定制的。然而,以下将解决您的问题,即使它不遵循理想的设计模式:

  1. 前向声明class B inside A.h及以上class A定义。
  2. 确保只在 A.h 成员函数声明中使用指向 class B 对象的指针或引用。
  3. 在 A.cpp 中包含 B.h。注意 .cpp 不是 .h

A.h

class B;

class A
{
public:
    A();
    ~A();

    B* method();
};

A.cpp

#include "A.h"
#include"B.h"

A::A()
{
}


A::~A()
{
}

B* A::method()
{
    return nullptr;
}

请注意,只传入和返回用户定义类型的指针/引用是有好处的,所以这可能不是一个糟糕的选择,特别是如果您只是想快速解决问题。