使用类类型向量的前向声明 - 不允许指向不完整类类型的指针

时间:2011-10-10 14:35:05

标签: c++ circular-dependency forward-declaration

我有两个课程,foobar

foo.h #include s bar.h并包含std::vectorbar个对象的指针。在运行时期间的某个时刻,bar必须访问指向其他bar对象的指针向量。因此,foo包含一个名为getBarObjects()的方法,它返回指针数组。

因此,我在bar.h中转发声明foo。我显然也必须转发声明我正在使用的方法 - foo::getBarObjects()。当这返回指向bar的指针数组时,我陷入了恶性循环。

我无法转发声明Bar,然后只需转发声明getBarObjects(),因为这会导致“不允许使用不完整的类型名称”。

foo.h中:

#include "bar.h"
#include <vector>

class foo {
    public:
         foo();
         ~foo();
         std::vector<bar*> getBarObjects();
    private:
         std::vector<bar*> barObjects;
}

bar.h:

class foo;
std::vector<bar*> foo::getBarObjects();        // error, doesn't know bar at this point

class bar {
    public:
        bar(foo *currentFoo);
        ~bar();
        bool dosth();
    private:
        foo *thisFoo;
}

bar.cpp:

#include "bar.h"

bool bar(foo *currentFoo) {
    thisFoo = currentFoo;
}

bool bar::dosth() {
    thisFoo->getBarObjects();        // error, pointer to inomplete class type is not allowed
}

如果我只是简单地包含其他方法,我稍后会在foo中遇到同样的问题。有什么建议吗?

3 个答案:

答案 0 :(得分:19)

您无法转发声明成员。

相反,bar.cpp应该#include foo.hbar.h。问题解决了。

通常,如果您使用序列:

  • 转发声明所有班级类型
  • 定义所有类类型
  • 班级成员

一切都会好的。

答案 1 :(得分:6)

除非您从其他头文件访问任一类的内部,否则您不必相互包含foo.h或bar.h。在头文件中根据需要声明类,然后包含源文件中的两个头文件。

<强> foo.h中

#include <vector>
class bar;
class foo {
    public:
         foo();
         ~foo();
         std::vector<bar*> getBarObjects();
    private:
         std::vector<bar*> barObjects;
};

<强> bar.h

class foo;
class bar {
    public:
        bar(foo *currentFoo);
        ~bar();
        bool dosth();
    private:
        foo *thisFoo;
}

<强> bar.cpp

#include "foo.h"
#include "bar.h"

bool bar(foo *currentFoo) {
    thisFoo = currentFoo;
}

bool bar::dosth() {
    thisFoo->getBarObjects();
}

答案 2 :(得分:1)

你忘了转发在foo.h中声明向量。您还从vector返回getBarObjects值,这可能不是您想要的,并且成员函数的前向声明是无用的。

另外:使用标头防护。首选适合您情况的智能指针(std::shared_ptrunique_ptr)优于原始指针。注意const ness。