C++對象模型-構造函數語意學
阿新 • • 發佈:2018-09-17
嘗試 修飾符 重載 情況 mes void 解釋 c++對象 pac
由於編譯器會盡可能的為所有的警告和錯誤做出解釋,但也因此導致了部分情況下的過度解析。
書中給的例子是編譯器過度解析,使用了類型轉換函數卻隱藏了真正的錯誤。
cin << intval;
int temp = cin.operator int();
temp << intval;
分析一下:
程序員的目的是實現讀取輸入,但是將 >> 寫成了 <<, istream並沒有重載 << 運算符,結果編譯器按照 << 左移位來解析
要想實現左移位,又必須將cin轉成整型。那麽編譯器會找istream有沒有類型轉換函數好將cin轉成整型後再進行移位操作
如果找到了,那麽,cin << intval; 正常執行了。並不報錯。
所以為了避免這種轉換發生,istream中使用了operator void*()來替換operator int()
隱式類型轉換雖然會"暗地裏"做一些轉換操作,但這種機制的好處也是顯而易見的。並且為了解決這個"暗地裏"的隱式操作,提供了一個修飾符,即explicit,類型轉換構造函數和類型轉換函數聲明前加上explicit關鍵字將阻止編譯器隱式類型轉換操作。任何嘗試隱式轉換的操作都會報錯。
如下:
#include<iostream> using namespace std; class A { public: //explicit A(int a):m_a(a) { cout << "construct A from int" << endl; } //explicit operator int() { cout <<"convert A to int " << end; return m_a; } public: int m_a; }; int main(void) { A a(5);//顯式類型轉換構造 A b = 5;//隱式類型轉換構造 int i = a;//隱式類型轉換函數 return 0; }
A a(5);總是正常的。
第一個explicit註釋掉,A a(5);運行正常;去掉該註釋,編譯提示:類型轉換失敗
第二個explicit註釋掉,int i = a;運行正常。 去掉該註釋 編譯提示:非法的存儲類,即賦值失敗。
C++對象模型-構造函數語意學