2011-09-01 22 views
4

考慮下面的代碼:提前聲明不轉換操作符的工作

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

代碼編譯,但問題是:是否有可能做使用我上面寫的前向聲明?

由於大部分 羅南

回答

2

號你A::operator B()創建B類型的對象。編譯器需要知道B的定義,以便能夠創建B類型的對象(例如,它需要知道執行堆棧指針計算有多大,它需要知道自定義構造函數是否需要)

0

不,這是不可能的。你不能聲明一個沒有完全定義的類型的對象。

0

您不能對前向聲明執行此操作,因爲編譯器需要知道B(及其默認ctor)的大小以用於操作符返回類型。沒有一個完整的類型,它不知道大小。

是的,它可能會從您在下面提供的定義中獲得此信息,但由於歷史原因,C和C++編譯器僅考慮先前在翻譯單元中出現的定義。

1

線:

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

創建B的對象,因爲B本不能發生沒有定義。

使用前向聲明可以聲明指向稍後可以在對象定義已知時創建的對象的指針,但不能直接創建對象。

0

無法在不知道定義的情況下創建類的對象。

將您的實現分爲.h和.cpp文件。所以,你可以有一個向前聲明class BA.h,包括其在A.cpp

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; 
} 
+0

而且人們可以使用A/B/B的定義,只是沒有在任何地方調用轉換運算符(如果我沒有錯的話)。這就是Qt爲GUI類型所做的事情:在頭文件中前向聲明'QVariant',在類聲明中放置合適的運算符聲明,幷包含「QVariant」,並在相應的* .cpp文件中定義運算符。 – mlvljr