前向声明不适用于转换运算符

Posted

技术标签:

【中文标题】前向声明不适用于转换运算符【英文标题】: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;

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

非常感谢 罗南

【问题讨论】:

【参考方案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 中包含它的定义

【讨论】:

以上是关于前向声明不适用于转换运算符的主要内容,如果未能解决你的问题,请参考以下文章

为啥析取赋值运算符 |= 不适用于布尔向量?

suppressWarnings() 不适用于管道运算符

运算符 = 不适用于 fstream

三元运算符不适用于 lambda 函数

PyMongo 聚合不适用于 $max 运算符

Fortran 派生类型:重载赋值运算符不适用于“参数”属性