【问题标题】:Field has incomplete type in forward declaration [duplicate]前向声明中的字段类型不完整[重复]
【发布时间】:2017-11-07 09:09:18
【问题描述】:

我使用以下简单文件重现错误。

上面写着:

字段的类型“Foo”不完整

bar.h:

class Foo;

class Bar{
    private:
        int x_;
        Foo foo_; // error: incomplete type

    public:
        void setx(int x) {x_ = x;};
        void increment(int);

};


class Foo{

public:
    void run(int y,Bar& bar) {bar.setx(y);};
};

void Bar::increment(int i){foo_.run(i,*this);}

成员foo_ 不能是引用或指针。原因是在我的实际代码中,无法在 Bar 的初始化列表中初始化 Foo。

【问题讨论】:

  • 要声明一个类的instance,需要类的完整定义。另一方面,要声明引用,只需要前向声明即可。我建议你试验一下你的类和成员函数定义的顺序。
  • 我无法在 Bar 的初始化列表中初始化 Foo。 那么你无法在 Bar 中创建 Foo 的实际实例。

标签: c++ forward-declaration


【解决方案1】:

您的问题可以简化为:

class Foo;

class Bar{
    Foo foo_; // error: incomplete type
};

在这里,您对类型 Foo 进行了前向声明,即没有完整定义的声明:在 C++ 中足以声明指针,但不像在 Bar 中那样声明具体实例。

要么给你的类一个完整的定义:

class Foo{
    // put details here
};

class Bar{
    Foo foo_; // OK
};

或使用(智能)指针,例如:

class Foo;

class Bar{
    std::unique_ptr<Foo> foo_; // OK
};

Bartek Banachewicz 所指的更改订单声明。

【讨论】:

  • 很有帮助,谢谢! ;)
【解决方案2】:

在这种情况下,它很简单:因为Foo 只使用对Bar 的引用,所以翻转它们就可以了:

class Bar; 

class Foo{
public:
    void run(int y,Bar& bar);
};

class Bar { ... };

void Foo::run(int y, Bar& bar) {
    bar.setx(y);
}

你还需要将Foo::run的主体移到下方,因为它实际上是在使用Bar成员函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 2013-11-04
    • 2014-12-25
    • 1970-01-01
    相关资源
    最近更新 更多