C++ virtual inheritace и typecasting/copy конструктор путаница
У меня есть код ниже:
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 A& a) не называется. Почему это так?
2 ответа:
B
также имеет неявно объявленный конструктор копирования, который объявлен какЭта неявно объявленная функция-член вызывается потому, что она лучше соответствует аргументу типаB(const B&);
C
, чем ваш объявленный пользователем конструкторB(const A&)
.
Вот что я получил, когда попробовал
clang++ -cc1 -ast-dump
на вашем кодеКак вы можете видеть, ваш класс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>)
B
имеет неявно объявленную(синтезированную компилятором) копию ctor.
inline B(B const &) throw():
что лучше соответствует аргументу типаC
, Как Джеймс Макнеллис сказал в своем ответе. Вот почему вы не видите вызоваB(const A& a)
, потому что он никогда не вызывается на самом деле.