简体   繁体   中英

C++ virtual inheritace and typecasting/copy constructor confusion

I have the code below:

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());
}

To my surprise B(const A& a) isn't called. Why is that?

B also has an implicitly declared copy constructor that is declared as

B(const B&);

This implicitly declared member function is called because it is a better match for the argument of type C than your user-declared constructor, B(const A&) .

This is what I got when I tried clang++ -cc1 -ast-dump on your code

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>)

As you can see your class B has an implicitly declared(compiler synthesized) copy ctor.

inline B(B const &) throw(): which is a better match for type C argument as James McNellis said in his answer . That's why you do not see a call to B(const A& a) because it never gets called actually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM