【问题标题】:forward declaration with vector of class type - pointer to incomplete class type not allowed带有类类型向量的前向声明 - 不允许指向不完整类类型的指针
【发布时间】:2011-10-10 14:35:05
【问题描述】:

我有两个班级,foobar

foo.h #includes bar.h 并包含一个 std::vector 指向 bar 对象的指针。在运行时的某个时刻,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 中遇到同样的问题。有什么建议吗?

【问题讨论】:

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


    【解决方案1】:

    您不能转发声明成员。

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

    一般来说,如果你使用顺序:

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

    一切都会好起来的。

    【讨论】:

    • 嗯,一个看似大问题的简单解决方案。谢谢!
    • 我一直在寻找这个解决方案几个小时。谢谢!
    • 我很想看看foo.hbar.hbar.cpp 遵循这个顺序后的样子。
    • @EpicPandaForce:和问题一样,只是从bar.h中删除了错误行,并在bar.cpp顶部附近添加了一行#include "foo.h"(至少,在bar::dosth() 的正文之前。
    【解决方案2】:

    您不必相互包含 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();
    }
    

    【讨论】:

      【解决方案3】:

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

      另外:使用标题保护。优先选择适合您情况的智能指针(std::shared_ptrunique_ptr)而不是原始指针。注意constness。

      【讨论】:

      • 我使用了标题保护,不用担心,我只是把它们放在这里,因为我输入了所有这些以避免与其他类名和诸如此类的混淆。不过谢谢
      猜你喜欢
      • 2021-12-31
      • 2012-08-15
      • 2015-10-09
      • 1970-01-01
      • 2017-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多