隱性類型轉換的突發奇想與失望

 在C++中,如果爲自定義類型(class)定義了類型轉換操作符或沒有explicit關鍵字修飾的單參數構造函數,在需要的時候,編譯器會自動執行隱式類型轉換。這是一個常識。隱式類型轉換是否需要的規則定義於編譯器內部,難以窺見,但就我理解,“需要”的意思之一應該是,如果不進行隱式類型轉換就找不到相應的重載函數,進行了就能找到的話,編譯器理應進行隱式類型轉換。

那天我看“委託”這個模式的時候,突然突發奇想,想到了利用隱式類型轉換進行非常簡單優美的委託的C++實現,不由大喜。

通常的B類要承擔A類的委託,代碼是這麼寫,略去構造函數等:

  1. class A
  2. {
  3. public:
  4.      f();
  5. };

  6. class B
  7. {
  8.      A * pa;
  9. public:
  10.      f() { pa->f(); }
  11. };

但是,如果B類要代理A類的很多函數甚至全部公有函數,重複地寫形如f() { pa->f(); }的函數定義就非常累人。

我當時的想法是:

  1. #include <iostream>

  2. using namespace std;

  3. class A
  4. {
  5.     public:
  6.         void a_func()
  7.         {
  8.             cout << "A's a_func() is called.";
  9.         }
  10. };

  11. class B
  12. {
  13.     A * pA;
  14.     public:
  15.         B() : pA(new A) {}
  16.         ~B() { delete pA; pA = 0;}
  17.         operator A() const { return *pA;}
  18. };


  19. int main()
  20. {
  21.     B b;
  22.     b.a_func();

  23.     return 0;
  24. }
理論上,編譯器應當發現B類並沒有成員函數a_func,並且發現如果執行隱式類型轉換就可以調用A類的a_func,從而進行隱式類型轉換。這樣,就實現了非常輕巧的“完全”委託,或曰一種不是繼承的繼承。當然,這純粹是一種hack,肯定不是在實際中應該推薦的代碼風格。

遺憾的是,gcc和VC 2005+對於上面這段程序甚至都無法通過編譯。這究竟是因爲編譯器不夠smart,還是我對C++標準理解有誤,我不知道。只是可惜了,這個突發奇想來的時候,我真的欣喜若狂,覺得這樣的代碼可以發揚開來,進行一種元編程,從而實現類似於lua中元表那樣的概念來處理method not found這樣的情況。

可惜夠不着,要不我還真的希望C++標準中明確一下隱式類型轉換的規則,最好加上這個情況和一些更有趣的情況,呵呵~P.S.一句,熱切盼望C++0x中.....




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章