前向声明不适用于转换运算符
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
中包含它的定义
【讨论】:
以上是关于前向声明不适用于转换运算符的主要内容,如果未能解决你的问题,请参考以下文章