gpt4 book ai didi

c++为什么虚拟继承允许防止进一步继承?

转载 作者:可可西里 更新时间:2023-11-01 16:38:51 24 4
gpt4 key购买 nike

相关:Does "virtual base class in the case of multilevel inheritance" have significance

我有一个可以继承的模板类,以便赋予一些选择功能。但是,它希望防止任何类进一步继承任何继承它的类。

以下似乎实现了这一点:

template<typename Child>
class SealingClass
{
public:
/*public methods etc*/
private:
SealingClass() {}
friend Child;
};

//simplify a bit:
#define Seal( x ) public virtual SealingClass< x >

现在,我可以继承上面的类,如下:

class NewClass: Seal(NewClass) {};

然后如果我再次尝试从 NewClass 继承,如下所示:

class AnotherClass: public NewClass {};

然后创建所述类的实例:

AnotherClass a;

我得到了预期的错误,关于 SealingClass 中的构造函数是私有(private)的。

所以,一切都如我所愿!

但是,我注意到如果我从 define.. 中删除 virtual 关键字。

#define Seal( x ) public SealingClass< x >

..我对 AnotherClass 的实例化现在工作正常。

我理解 virtual 关键字,在此上下文中,意味着在可能存在多个实例的多重继承(例如菱形继承)的情况下,只定义基类的一个实例,导致模棱两可的函数调用等。

但是,为什么它会影响上面的功能呢?

谢谢:)

最佳答案

如果使用虚继承,最派生类型必须做这个虚基类的初始化。如果不使用虚拟继承,则直接派生的类型必须进行初始化。

因此,private ctor 不会阻止派生类型NewClass 初始化直接基类SealingClassAnotherClass 也不必如果 NewClass 没有被虚拟继承,则初始化它。


一些例子:

template<typename Child>
class SealingClass {
public: // for now
SealingClass() {}
};

class NewClass : public SealingClass<T> {
public:
NewClass() : SealingClass<T>() {} // allowed, SealingClass<T> is a
// direct base class
};

class AnotherClass : public NewClass {
public:
AnotherClass() : NewClass() {} // allowed, NewClass is a
// direct base class
AnotherClass() : SealingClass<T>() {} // not allowed, SealingClass<T> is
// no direct nor a virtual base class
};


class NewClass_v : public virtual SealingClass<T> {
public:
NewClass_v() : SealingClass<T>() {} // allowed, SealingClass<T> is a
// direct base class
};

class AnotherClass_v : public NewClass_v {
public:
AnotherClass_v() : NewClass_v() {} // allowed, NewClass_virt is a
// direct base class
AnotherClass_v() : SealingClass<T>() {} // allowed, SealingClass<T> is a
// virtual base class
};

现在,如果 SealingClass 的构造函数是私有(private)的,由于 private 访问说明符,AnotherClass_virt 不允许调用这个构造函数,而不是做 friend 。

如果你省略了基类的显式初始化(​​无论是虚拟的还是直接的),它是默认初始化的([class.base.init]/8),即默认的ctor被隐式调用(但你仍然必须有权访问 ctor,因此它与显式编写对默认 ctor 的调用相同)。


一些引述:

[class.base.init]/1

In the definition of a constructor for a class, initializers for direct and virtual base subobjects and non-static data members can be specified by a ctor-initializer

[class.base.init]/7

A mem-initializer where the mem-initializer-id denotes a virtual base class is ignored during execution of a constructor of any class that is not the most derived class.

[class.base.init]/10

In a non-delegating constructor, initialization proceeds in the following order:

  • First, and only for the constructor of the most derived class, virtual base classes are initialized in the order they appear on a depth-first left-to-right traversal of the directed acyclic graph of base classes, where “left-to-right” is the order of appearance of the base classes in the derived class base-specifier-list.
  • Then, direct base classes are initialized in declaration order as they appear in the base-specifier-list (regardless of the order of the mem-initializers).

强调我的。

关于c++为什么虚拟继承允许防止进一步继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16288824/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com