C++虚拟继承和类型转换/复制构造函数混淆

发布于 2024-09-24 11:49:58 字数 349 浏览 7 评论 0原文

我有下面的代码:

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) 没有被调用。这是为什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

从此见与不见 2024-10-01 11:49:58

B 还有一个隐式声明的复制构造函数,声明为 调用

B(const B&);

此隐式声明的成员函数是因为它比用户声明的类型更匹配 C 类型的参数构造函数,B(const A&)

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

再可℃爱ぅ一点好了 2024-10-01 11:49:58

这是我在您的代码上尝试 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 有一个隐式声明的(编译器合成的)复制构造函数。

inline B(B const &) throw(): 这是类型 C 参数更好的匹配 James McNellis他的回答。这就是为什么您看不到对 B(const A& 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文