抽象类的虚拟基类的初始化 [英] Initialization of virtual base class of abstract class

查看:223
本文介绍了抽象类的虚拟基类的初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑代码:

#include <iostream>

using std::cout;
using std::endl;

struct A
{
    virtual void foo(){ };

    A()
    {
        cout << "A()" << endl;
    }
};

struct B : virtual A
{
    virtual void bar() = 0;

    B() : A() //mem-initializer of virtual base class
    {
        cout << "B()" << endl;
    }
};

struct C : B
{
    void bar(){ };
    C() : B()
    {
        cout << "C()" << endl;
    }
};

C c;

int main()
{
    //A()
    //B()
    //C()
    //Is output
}

演示

我写了代码以了解 12.6的规则注释。 2/8 N37973


[注意:抽象类(10.4)绝不是大多数派生类,因此
它的构造函数从不初始化虚拟基类,因此
对应的mem初始化器可以省略。 - end note]

[Note: An abstract class (10.4) is never a most derived class, thus its constructors never initialize virtual base classes, therefore the corresponding mem-initializers may be omitted. — end note]

如果我们在 B()并使基类 A 作为非虚拟,我们将有相同的结果。

If we omit mem-initializer in the B() and make the base class A as non-virtual we'll have the same result.

实际

那么我引用的注释的目的是什么?

So what purpose of the note that I cited?

推荐答案

它说的是这样的:

#include <iostream>

using std::cout;
using std::endl;

struct A
{
    virtual void foo(){ };

    // N.B.: no default ctor
    A(int)
    {
        cout << "A(int)" << endl;
    }
};

struct B : virtual A
{
    virtual void bar() = 0;

    B()
    {
        cout << "B()" << endl;
    }
};

struct C : B
{
    void bar(){ };
    C() : A(10), B()
    {
        cout << "C()" << endl;
    }
};

C c;

int main()
{

}

如果 A 不是 B B的虚拟基础不是抽象的,则 B :: B()必须有适当的 mem-initializer $ c> A ;然而,由于 B 是抽象的, A 是虚拟基础, B 的构造函数不会实际构造 A ,可以省略 mem-initializer 。注意,g ++目前不实现这个规则,并且仍然需要 B (它将永远不会实际使用)的 mem-initializer 。 Cl,但是。 演示

If A weren't a virtual base of B, or B weren't abstract, then B::B() must have an appropriate mem-initializer for A; however, since B is abstract and A is a virtual base, and B's constructor will never actually construct A, the mem-initializer can be omitted. Note that g++ currently does not implement this rule and still requires a mem-initializer for B (which it will never actually use). Clang does, however. Demo.

另请参见 CWG问题257 ,介绍了此规则,其后的 CWG问题1658 。相关的GCC错误报告是错误19249 53878

See also CWG issue 257, which introduced this rule, with the phrasing further altered later by CWG issue 1658. The relevant GCC bug reports are bug 19249 and 53878.

这篇关于抽象类的虚拟基类的初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆