2015-11-30 52 views
3

如果我用一個整數作爲參數(而不是'通用'對象)調用「func(const generic & ref)」,構造函數generic(int _a)將調用來創建一個新的對象。傳遞給const引用的C++文本導致自動構建

class generic { 
public: 
    int a; 
    generic() {} 
    generic(int _a) : a(_a) { 
     std::cout << "int constructor was called!"; 
    } 
    generic(const generic& in) : a(in.a) { 
     std::cout << "copy constructor was called!"; 
    } 
}; 

void func(const generic& ref) { 
    std::cout << ref.a; 
} 

int main() { 
    generic g(2); 
    func(g); // this is good. 
    func(generic(4)); // this is good. 
    func(8); // this is good...... ? 
    return 0; 
} 

最後一個「func(8)」調用使用構造函數generic(int _a)創建一個新對象。這種建築有沒有名字?程序員不應該在傳遞參數之前顯式構造一個對象嗎?像這樣:

func(generic(8)); 

單獨傳遞整數(除了保存時間)有什麼好處嗎?

+0

http://en.cppreference.com/w/cpp/language/implicit_cast – szczurcio

+1

你有一個構造函數,它需要一個'int',因此編譯器會使用它來創建'generic'。如果您不想使用該構造函數,請使用'explicit'關鍵字。 –

回答

4

此行爲是overload resolution過程的一部分 - 具體地說。

當您撥打func()時,編譯器會構造一個候選列表。只有一個候選人,func(const generic& ref),所以編譯器試圖找出如何撥打電話。

它看到沒有定義func(int),所以它試圖找到從intgeneric的轉換路徑。由於generic的構造函數採用int,並且沒有其他轉換允許執行相同的調用,編譯器將採用構造+調用路徑。

編譯器檢查三兩件事,在順序從高到低的優先級:

  • 精確匹配
  • 促進
  • 轉換

這意味着簽名的精確匹配勝過需要晉升的比賽,而需要晉級的比賽勝過需要轉換的比賽。

有關如何應用隱式轉換的信息,請參閱上面鏈接文檔中的「隱式轉換序列的排名」。

3

是否有這種建築的名稱?程序員不應該在傳遞參數之前顯式構造一個對象嗎?

如果你不希望這樣的事情發生,你可以將explicit specifier添加到您的構造函數:

explicit generic(int _a) : a(_a) 
{ 
    std::cout << "int constructor was called!"; 
} 

從cppreference頁的摘錄:即宣告

的構造方法沒有函數說明符explicit被稱爲轉換構造函數。

默認情況下,隱式構造函數調用在這種情況下是允許的。

單獨傳遞整數(除了保存時間)有什麼好處嗎?

是否與您通話func(8)func(generic(8))該方法不會改變什麼代碼執行給你寫的代碼。如果您要增加一個func的過載需要int而不是generic,則呼叫會突然變得不同。所以,儘管這最終是一個意見問題,但我認爲你最好通過使用func(generic(8))來明確。