1. 程式人生 > >C++對象模型-構造函數語意學

C++對象模型-構造函數語意學

嘗試 修飾符 重載 情況 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++對象模型-構造函數語意學