[英]Rules for deriving from a non-virtual descendant with virtual base class
If I have a hierarchy of C++ classes where the base class has a member function that is declared as virtual, but derived classed do not declare that function as virtual, how far into the class hierarchy does the virtualization carry.如果我有一个 C++ 类的层次结构,其中基类有一个声明为虚拟的成员函数,但派生类不将该函数声明为虚拟的,那么虚拟化在类层次结构中进行了多远。 For example, given the code is the return value of MyFunc2 well defined?例如,给定的代码是否明确定义了 MyFunc2 的返回值?
class A
{
public:
virtual int x() { return 1; }
}
class B : public A
{
public:
int x() { return 2; }
};
class C: public B
{
public:
int x() { return 3; }
};
int MyFunc1(f &A)
{
return f.x();
}
int MyFunc2(f &B)
{
return f.x();
}
int MyFunc3()
{
C c;
return MyFunc1(c);
}
int MyFunc4()
{
C c;
return MyFunc2(c);
}
From similar question here , it would appear that the virtual characteristic is propagated forward to all classes once it is virtual in the base class, but I'm wondering how well defined this is, specifically is Bx() virtual by implication of being derived from A.从这里的类似问题来看,一旦它在基类中是虚拟的,虚拟特性就会向前传播到所有类,但我想知道这是如何定义的,特别是 Bx() 虚拟的含义是从一种。
Overrides in subclasses are implicitly virtual too.子类中的覆盖也是隐式虚拟的。 You can specify the virtual
keyword again, but it does not make any difference, although it's often considered good practice.您可以再次指定virtual
关键字,但它没有任何区别,尽管它通常被认为是好的做法。 It is absolutely "well defined" in the standard.它在标准中绝对是“明确定义的”。
Starting C++11, you have an even better option: you can tag virtual methods in subclasses with override
to ensure they actually override something.从 C++11 开始,您有一个更好的选择:您可以使用override
标记子类中的虚拟方法,以确保它们实际上覆盖了某些东西。 This prevent not actually overriding parent methods because of a small prototype difference and will trigger errors if you change the base virtual prototype but forget to adapt the overrides.这可以防止由于较小的原型差异而不实际覆盖父方法,并且如果您更改基本虚拟原型但忘记调整覆盖,则会触发错误。
Yes, the virtual
characteristic is "propagated" (to use your wording) to all derived classes.是的, virtual
特征“传播”(使用您的措辞)到所有派生类。 If derived classes declare and define a member function with the same signature as an inherited virtual function, they override it.如果派生类声明并定义了与继承的虚函数具有相同签名的成员函数,则它们会覆盖它。
C++11 introduced the final
modifier which derived classes can use to prevent their descendents from further-overriding an inherited virtual function. C++11 引入了final
修饰符,派生类可以使用它来防止其后代进一步覆盖继承的虚函数。 However, the function is still technically virtual (eg given a pointer to base, a polymorphic call of p->func()
calls the func()
corresponding to the actual type of the object) .... it just cannot be overridden.然而,该函数在技术上仍然是虚拟的(例如,给定一个指向 base 的指针, p->func()
的多态调用调用对应于对象实际类型的func()
)......它只是不能被覆盖。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.