【问题标题】:Circular dependency on inheritance in C++ [duplicate]C ++中对继承的循环依赖[重复]
【发布时间】:2018-12-23 20:07:50
【问题描述】:

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

文件:A.h

#include "B.h"

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

文件:B.h

#include "A.h"

class B : public A {
...
}

我在 B 类文件中收到此错误“在‘{’标记之前的预期类名”。我尝试在 A.h 和 B.h 中添加类声明,但没有任何效果。我想这是一个循环依赖问题。有人可以帮我吗?

【问题讨论】:

  • 另外,当我尝试转发类声明时,我得到:“不完整类型的无效使用...”
  • 看到这个answer
  • 它没有用。另外,我需要在 B 类中使用其他 A 方法。
  • 在您的真实代码中,您的基类(即A)是否真的知道派生类型(即B)?

标签: c++ dependencies


【解决方案1】:

以下内容对我有用。如果您仍然遇到问题,您应该提供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;
}

【讨论】:

    【解决方案2】:

    这称为“前向声明”。例如:

    #include "B.h"
    
    class B;
    
    class A {
    ...
    B method();
    };
    

    只要你只声明方法,而不实际定义它,这使得声明方法成为可能。

    一个实际的 C 文件将包含这两个头文件,以及两个类的定义,现在可以定义、调用和使用类方法。

    您可能希望开始查看标准 C++ 标头,例如 &lt;iostream&gt;、&lt;string&gt; 等。 C++ 库中的所有模板通常都具有复杂的相互依赖关系。

    您可能会发现您的 C++ 编译器以相当严格的顺序构建了它的头文件。首先是所有的前向声明和类声明。并且只有在声明了所有内容之后,您才会看到实际的模板声明。

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

    【讨论】:

    • 您可以删除#include "B.h"/
    • 不,我不能。当我删除它时,编译器说 B 没有在这个范围内声明。
    【解决方案3】:

    有许多解决方案可以解决您的问题,但最好的一个是针对您的课程设计量身定制的(我们对此一无所知)。但是,即使它不遵循理想的设计模式,以下内容也会解决您的问题:

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

    啊.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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 2018-04-21
      • 1970-01-01
      • 1970-01-01
      • 2018-05-07
      相关资源
      最近更新 更多