循环依赖于C ++中的继承

时间:2015-03-16 01:24:08

标签: c++ dependencies

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

档案:A.h

#include "B.h"

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

档案:B.h

#include "A.h"

class B : public A {
...
}

我收到此错误“B类文件中'{'token'之前的预期类名。我已经尝试在A.h以及B.h中添加类声明,但没有任何效果。我想这是一个循环依赖问题。有人能帮助我吗?

3 个答案:

答案 0 :(得分:0)

这称为"前向声明"。例如:

#include "B.h"

class B;

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

只要您只声明方法,并且实际上没有定义它,就可以声明方法。

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

您可能希望开始查看标准C ++标头,例如<iostream><string>和其他标头。 C ++库中的所有模板通常都具有复杂的相互依赖关系。

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

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

答案 1 :(得分:0)

以下适用于我。如果您仍然遇到问题,请提供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 :(得分:0)

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

  1. 在A.h及以上A类定义中转发声明B类。
  2. 确保在A.h成员函数声明中仅使用指针或对B类对象的引用。
  3. 在A.cpp中加入B.h.注意.cpp不是.h
  4. 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;
    }
    

    请注意,只有传入和返回用户定义类型的指针/引用才有优点,所以这可能不是一个糟糕的选择,特别是如果你只是在寻找快速修复。