2010-03-15 116 views
3

爲什麼在下面的代碼中調用Child類的轉換器構造函數?C++爲什麼隱式調用轉換器構造函數?

我的意思是,它會通過Child轉換器構造函數自動將Base轉換爲Child。下面的代碼編譯,但不應該不是編譯,因爲我還沒有提供bool Child::operator!=(Base const&)

class Base 
{ 
}; 

class Child : public Base 
{ 
public: 
    Child() {} 
    Child(Base const& base_) : 
    Base(base_) 
    { 
    std::cout <<"should never called!"; 
    } 
    bool operator!=(Child const&) 
    { 
    return true; 
    } 
}; 

void main() 
{ 
    Base base; 
    Child child; 

    if(child != base) 
    std::cout << "not equal"; 
    else 
    std::cout << "equal"; 
} 
+0

我想這篇文章可能是一個很好的用例,爲什麼明確的關鍵字存在。 – sivabudh 2010-03-15 23:44:44

+0

我應該將副本構造函數的標題重命名爲轉換器構造函數嗎? – sivabudh 2010-03-15 23:53:03

回答

3

因爲您提供了一個轉換構造函數。如果你不希望編譯器使用

Child(Base const& base_) 

構造Base對象自動轉換爲Child,使其明確:

explicit Child(Base const& base_) 

這種方式,構造函數纔會被調用時,您明確指定它,像背景:

Child ch(base); 
foo(Child(base)); 
new Child(base); 
+1

謝謝。現在我明白了明確的關鍵字的需求。 – sivabudh 2010-03-15 23:42:27

0

因爲你不提供任何操作=()以基本作爲參數:編譯器將嘗試「W帽子他可以「,並且看到有一個可以調用的參數類型(Child)的轉換構造函數。所以它使用它來使!=工作。

1

因爲兒童不能與基地相比 - 它只能與另一個孩子比較。因此,您的編譯器會創建Base to Child的隱式副本,以便進行轉換。如果您將代碼更改爲:

class Child : public Base 
{ 
public: 
    Child() {} 
    explicit Child(Base const& base_) : 
    Base(base_) 
    { 
    std::cout <<"should never called!"; 
    } 
    bool operator!=(Child const&) 
    { 
    return true; 
    } 
}; 

您會發現它不再編譯。

6

帶簽名Child(Base const& base_)的函數不是複製構造函數(右側類型與左側不一樣)。爲了在main中進行比較,編譯器可以隱式使用該構造函數來強制一種類型。爲了防止這個標記的構造函數explicit

相關問題