问题创建抽象类,没有虚拟纯方法C++
我想创建一个具有共同虚拟基类的两个类的子类。此外,我希望此类是抽象的(无法创建其实例,但也不需要称呼虚拟基类的CTOR)。
示例代码:
#include <cstdio>
class CommonBaseClass {
public:
virtual void DoSomething() = 0;
virtual void DoSomethingElse() = 0;
CommonBaseClass(int a) {}
};
class ClassA : public virtual CommonBaseClass {
public:
virtual void DoSomething() override {
printf("SOMETHING\n");
}
ClassA() {};
};
class ClassB : public virtual CommonBaseClass {
public:
virtual void DoSomethingElse() override {
printf("SOMETHING ELSE\n");
}
ClassB() {};
};
class TargetClass : //I will never instantiate this class
public ClassA,
public ClassB
{
public:
TargetClass() : ClassA(), ClassB() {} //I don't want to call the CommonBaseClass ctor
};
class SubclassOfTarget :
public TargetClass
{
public:
SubclassOfTarget(int a) : CommonBaseClass(a), TargetClass()
{}
};
int main()
{
SubclassOfTarget c(15);
c.DoSomething();
c.DoSomethingElse();
}
如果您尝试编译此程序,您会发现编译器抱怨targetClass
不调用CommonBaseclass的CTOR。
I want to create a class that is a subclass of two classes that have a common virtual base class. Furthermore, I want this class to be abstract (not be able to create instances of it, but also not needing to call the ctor of the virtual base class).
Sample code:
#include <cstdio>
class CommonBaseClass {
public:
virtual void DoSomething() = 0;
virtual void DoSomethingElse() = 0;
CommonBaseClass(int a) {}
};
class ClassA : public virtual CommonBaseClass {
public:
virtual void DoSomething() override {
printf("SOMETHING\n");
}
ClassA() {};
};
class ClassB : public virtual CommonBaseClass {
public:
virtual void DoSomethingElse() override {
printf("SOMETHING ELSE\n");
}
ClassB() {};
};
class TargetClass : //I will never instantiate this class
public ClassA,
public ClassB
{
public:
TargetClass() : ClassA(), ClassB() {} //I don't want to call the CommonBaseClass ctor
};
class SubclassOfTarget :
public TargetClass
{
public:
SubclassOfTarget(int a) : CommonBaseClass(a), TargetClass()
{}
};
int main()
{
SubclassOfTarget c(15);
c.DoSomething();
c.DoSomethingElse();
}
If you try to compile this program, you will see that the compiler complains that TargetClass
does not call the ctor of CommonBaseClass.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
确实(因为C ++ 11),抽象类的构造函数无需初始化其虚拟基类。在没有任何特定启用的虚拟功能的情况下,制作班级抽象的通常方法是使破坏者纯虚拟。
通过此更改,您的程序编译:
请注意,即使它是纯粹的,也必须定义破坏者。由于一份声明不能同时具有
= 0
和{
body}
} = = =默认值在这种情况下,需要超出班级定义。尽管实际上,建议始终确保任何多态类别(至少具有一个虚拟功能或虚拟基类)具有虚拟破坏者。这使得
delete
基本类类型的指针指向具有不同动态类型的对象的指针是合法的。而且,使用通常的VTable实现,将虚拟破坏者添加到已经是多态性的类中几乎没有成本。遵循此建议,您还将添加Virtual〜commonBaseclass()= default;
commonbaseclass ,然后其他类也自动具有虚拟击路仪。然后,您可以使用样式〜targetClass()Override = 0;
来声明纯虚拟驱动器。It's true (since C++11) the constructors of an abstract class don't need to initialize their virtual base classes. The usual way to make a class abstract without any specific unimplemented virtual functions is to make the destructor pure virtual.
With this change, your program compiles:
Note the destructor must be defined, even though it is pure. Since one declaration can't have both
= 0
and a{
body}
or= default
, that destructor definition in this case needs to be outside the class definition.Though actually, it's recommended to always make sure any polymorphic class (having at least one virtual function or virtual base class) has a virtual destructor. This makes it legal to
delete
a pointer of base class type pointing at an object with a different dynamic type. And with the usual vtable implementations, there's nearly no cost to add the virtual destructor to a class which is already polymorphic. Following this advice, you would also addvirtual ~CommonBaseClass() = default;
toCommonBaseClass
, and then the other classes automatically also have virtual destructors. And then you might use the style~TargetClass() override = 0;
for the declaration of the pure virtual destructor.您可以使用如下的纯虚拟驱动器。即使它是纯虚拟的,您仍然需要实施它。您不需要在派生类中声明破坏者。
You can use a pure virtual destructor as follows. Even although it is pure virtual, you still need to implement it. You do not need to declare destructors in the derived classes.