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

时间:2011-09-01 15:29:06

标签: c++ operators forward-declaration

考虑下一个代码:

#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;
}

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

非常感谢 RONEN

6 个答案:

答案 0 :(得分:4)

是的,只要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;
}

答案 1 :(得分:2)

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

答案 2 :(得分:1)

该行:

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

创建B的对象。由于未定义B,所以不会发生这种情况。

前向声明允许您声明指向对象的指针,这些对象可以在以后知道对象定义时创建,但是您无法直接创建对象。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

在不知道其定义的情况下,无法创建类的对象。

将您的实现分成.h和.cpp文件。因此,您可以在class B中提供前瞻性声明A.h,并将其定义包含在A.cpp