2010-09-21 93 views
3

我有代碼如下:C++虛擬inheritace和類型轉換/拷貝構造混亂

class A 
{ 
}; 

class B: public virtual A 
{ 
public: 
    B() 
    { 
     cerr << "B()"; 
    } 
    B(const A& a) 
    { 
     cerr << "B(const A&)"; 
    } 
}; 

class C: public B 
{ 

}; 

int main(int argc, char **argv) 
{ 
    B *b = new B(C()); 
} 

令我驚訝B(const的甲&一個)不被調用。這是爲什麼?

+0

這與使用虛擬繼承的事實沒有任何關係;非虛擬繼承會表現出相同的行爲。 – 2010-09-21 15:23:09

回答

8

B還具有以下

B(const B&); 

這隱式聲明的成員函數被調用,因爲它是C類型的參數比你的用戶聲明的構造更好的匹配所聲明的隱式聲明的拷貝構造函數,B(const A&)

1

這就是我,當我在你的代碼

class B : virtual public A { 
    class B; 
public: 
    B() : A() (CompoundStmt 0xb85950 <a.cpp:9:5, line:11:5>) 


    B(A const &a) : A() (CompoundStmt 0xb859c0 <a.cpp:13:5, line:15:5>) 


    inline B &operator=(B const &) throw(); 
    inline void ~B() throw(); 
    inline B(B const &) throw() : A((ImplicitCastExpr 0xb86a10 <a.cpp:5:7> 'clas 
s A const' <UncheckedDerivedToBase (virtual A)> lvalue 
    (DeclRefExpr 0xb869ec <col:7> 'class B const' ParmVar='' 0xb86170)) 
) (CompoundStmt 0xb86ab0 <a.cpp:5:7>) 

試圖clang++ -cc1 -ast-dump正如你可以看到你的B類有一個隱式聲明(編譯器合成的)複製構造函數。

inline B(B const &) throw():這是C類型的更好匹配,James McNellis表示his answer。這就是爲什麼你沒有看到B(const A& a)的呼叫,因爲它從來沒有被實際調用。