【问题标题】:How do I get over this forward declaration error?如何克服这个前向声明错误?
【发布时间】:2015-03-06 01:08:05
【问题描述】:

我正在尝试做一个类 A 的准系统示例,它通过传递对自身的引用为依赖类 B 提供回调方法。我制作的最好的如下:

啊.h

#ifndef A_H
#define A_H

#include "b.h"

namespace b {
    class ClassB;
}

namespace a {

    class ClassA {
    public:
        ClassA();
        b::ClassB* m_b;
        void callback(const std::string& msg);
    };
}

#endif 

a.cc

#include "a.h"

a::ClassA::ClassA() {
    m_b = new b::ClassB(this);
}

void a::ClassA::callback(const std::string& msg) {
    std::cout << msg << '\n';
}

int main(void)
{
    a::ClassA* doit = new a::ClassA();
    delete doit;
    return 0;
}

b.h

#ifndef B_H
#define B_H

#include <iostream>
#include <string>

namespace a {
    class ClassA;
}

namespace b {
    class ClassB{
    public:
        ClassB(a::ClassA* a_inst);
    };
}

#endif

b.cc

#include "b.h"

namespace b {

    ClassB::ClassB(a::ClassA* a_inst) {
        a_inst->callback("Call me maybe");
    }
}

这是我能得到的最接近的编译,但我留下了以下错误:

b.cc: In constructor 'b::ClassB::ClassB(a::ClassA*)':
b.cc:6:9: error: invalid use of incomplete type 'struct a::ClassA'
b.h:8:8: error: forward declaration of 'struct a::ClassA'

我该如何解决这个问题?有没有更好的方法来构建这种关系?

【问题讨论】:

    标签: c++ forward-declaration


    【解决方案1】:

    在您的文件b.cc 中,您必须包含a.h。
    在 .h 文件中你不能因为多重包含,但由于 .cc 文件不包含,它们可以包含任何他们想要的。

    注意:

    您不应在 a.h 文件中转发声明 b,因为它已在 b.h 中声明并且您包含了它。

    您也可以,如 @chris 所述,删除 a.h 中的 #include "b.h" 并将其放入您的 a.cc。

    【讨论】:

    • 你应该在最后一部分走另一条路。您只需要一个前向声明,因此不要包含该文件。 a.cc 是需要包含它的内容。
    • 这与您在回答中所说的相反。您更喜欢包含文件而不是使用前向声明。
    • 您建议从头文件中删除包含,改为转发声明并从源文件中包含 onmy ?
    • 是的,您应该尽可能选择前向声明。当具有前向声明类的文件发生更改时,您将立即获得不必重新编译该文件的好处。在某些情况下,需要解决循环依赖关系。
    • 我明白你的意思。当我处于 OP 的情况时,我习惯于做一个前向声明和一个包含。我要编辑我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多