【问题标题】:Forward declaration doesn't work with conversion operator前向声明不适用于转换运算符
【发布时间】:2011-09-01 15:29:06
【问题描述】:

考虑下一个代码:

#include <iostream>
using namespace std;


class B;

class A
{
public:

    A() { p = 1;}
    int p;
    operator B() {B b; b.x = this->p; return b;}
};


class B
{
public:
    int x;
};

int main()
{

    A a;
    B b = a;
    return 0;
}

我正在尝试将 A 转换为 B ,但我得到以下编译器尖叫声:

..\main.cpp:13: error: return type 'struct B' is incomplete

当我这样做时:

#include <iostream>
using namespace std;

class B
{
public:
    int x;
};

class A
{
public:

    A() { p = 1;}
    int p;
    operator B() {B b; b.x = this->p; return b;}
};


int main()
{
    A a;
    B b = a;
    return 0;
}

代码可以编译,但问题是:是否可以使用我上面写的前向声明来做到这一点?

非常感谢 罗南

【问题讨论】:

    标签: c++ operators forward-declaration


    【解决方案1】:

    可以,只要A::operator B的定义遵循class B的定义即可。

    #include <iostream>
    using namespace std;
    
    
    class B;
    
    class A
    {
    public:
    
        A() { p = 1;}
        int p;
        operator B();
    };
    
    
    class B
    {
    public:
        int x;
    };
    
    inline A::operator B() {B b; b.x = this->p; return b;}
    
    
    int main()
    {
    
        A a;
        B b = a;
        return 0;
    }
    

    【讨论】:

    • 并且可以使用没有 B 定义的 A 类,只是不要在任何地方调用转换运算符(如果我没记错的话)。这就是 Qt 对其 GUI 类型所做的事情:在标题中前向声明 QVariant,在类声明中放置适当的运算符声明,并包含“QVariant”并在适当的 *.cpp 文件中定义运算符。
    【解决方案2】:

    没有。您的A::operator B() 创建了一个B 类型的对象。编译器需要知道B 的定义才能创建B 类型的对象(例如,它需要知道执行堆栈指针计算的大小。它需要知道是否自定义需要调用构造函数。)

    【讨论】:

      【解决方案3】:

      行:

      operator B() {B b; return b;}
      

      创建一个 B 的对象。这不可能发生,因为 B 没有定义。

      前向声明让您可以声明指向对象的指针,这些指针可以在知道对象定义后创建,但您不能立即创建对象。

      【讨论】:

        【解决方案4】:

        不,这是不可能的。您不能声明未完全定义的类型的对象。

        【讨论】:

          【解决方案5】:

          您不能使用前向声明来执行此操作,因为编译器需要知道运算符返回类型的 B(以及它的默认 ctor)的大小。没有完整的类型,它就无法知道大小。

          是的,它可能可以从您在下面提供的定义中获取此信息,但由于历史原因,C 和 C++ 编译器只考虑在翻译单元中出现的定义。

          【讨论】:

            【解决方案6】:

            在不知道其定义的情况下创建类的对象是不可能的。

            将您的实现分成 .h 和 .cpp 文件。所以你可以在A.h 中有一个前向声明class B 并在A.cpp 中包含它的定义

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-05-17
              • 1970-01-01
              相关资源
              最近更新 更多