在C++中,如果爲自定義類型(class)定義了類型轉換操作符或沒有explicit關鍵字修飾的單參數構造函數,在需要的時候,編譯器會自動執行隱式類型轉換。這是一個常識。隱式類型轉換是否需要的規則定義於編譯器內部,難以窺見,但就我理解,“需要”的意思之一應該是,如果不進行隱式類型轉換就找不到相應的重載函數,進行了就能找到的話,編譯器理應進行隱式類型轉換。
那天我看“委託”這個模式的時候,突然突發奇想,想到了利用隱式類型轉換進行非常簡單優美的委託的C++實現,不由大喜。
通常的B類要承擔A類的委託,代碼是這麼寫,略去構造函數等:
class A
{
public:
f();
};
class B
{
A*pa;
public:
f(){pa->f();}
};
但是,如果B類要代理A類的很多函數甚至全部公有函數,重複地寫形如f(){ pa->f();}的函數定義就非常累人。
我當時的想法是:
#include <iostream>
using namespace std;
class A
{
public:
void a_func()
{
cout<<"A's a_func() is called.";
}
};
class B
{
A* pA;
public:
B():pA(new A){}
~B(){delete pA;pA=0;}
operatorA() const {return *pA;}
};
int main()
{
B b;
b.a_func();
return 0;
}
理論上,編譯器應當發現B類並沒有成員函數a_func,並且發現如果執行隱式類型轉換就可以調用A類的a_func,從而進行隱式類型轉換。這樣,就實現了非常輕巧的“完全”委託,或曰一種不是繼承的繼承。當然,這純粹是一種hack,肯定不是在實際中應該推薦的代碼風格。
遺憾的是,gcc和VC 2005+對於上面這段程序甚至都無法通過編譯。這究竟是因爲編譯器不夠smart,還是我對C++標準理解有誤,我不知道。只是可惜了,這個突發奇想來的時候,我真的欣喜若狂,覺得這樣的代碼可以發揚開來,進行一種元編程,從而實現類似於lua中元表那樣的概念來處理method not found這樣的情況。
可惜夠不着,要不我還真的希望C++標準中明確一下隱式類型轉換的規則,最好加上這個情況和一些更有趣的情況,呵呵~P.S.一句,熱切盼望C++0x中.....