#include <iostream>
struct A {
virtual void f(){
std::cout<<"1\n";
}
};
struct B : A {
};
struct C : A {
void f(){
std::cout<<"abc\n";
}
};
struct D : B, C {
};
int main(){
D mostDerived{};
D* ptr = &mostDerived;
B* bptr = ptr;
A* aptr = bptr;
aptr->f();
}
考虑上面的代码,outcome是1
。但是,由于标准所说,我对此结果感到怀疑:
class.virtual#def:final_overrider
为方便起见,我们说任何虚函数都将覆盖自身。除非其中S是基类子对象的最派生类(如果有),类对象S 的虚拟成员函数C :: vf是最终的重写器。声明或继承另一个重写vf的成员函数。
除构造函数外,基类的成员被称为由派生类继承。基类的构造方法也可以按照[namespace.udecl]中的描述进行继承。
IIUC,将B和A
中类型C
的基类子对象分别视为A1
,A2
。在我的示例中,最派生的类是D
,根据上述规则,对于类B
,最终的替代者是A::f
,它是从A
继承的类C
,最终的替代者是C::f
,它是在类C
中声明的,对于类D
,它是从B
和C
派生的,因此它将继承B
和C
的这些成员。由于C::f
覆盖A::f
,因此根据规则unless **the most derived class of which S is a base class subobject** (if any) declares or **inherits another member function that overrides vf**
,将A1
视为S
(即A1
是...的子对象类D
),其中D
继承了another member function that overrides vf
的{{1}}。这意味着,子对象C::f
的最终替代应该为A1
,因此,我想知道为什么不是C::f
而不是abc
的结果?
另一个问题是:
1
struct A {
virtual void f(){
std::cout<<"1\n";
}
};
struct B : A {
void f(){}
};
struct C : A {
void f(){}
};
struct D : B, C {
};
和B::f
都覆盖了虚函数C::f
,但它们彼此不覆盖,因此A::f
继承了哪个功能?还是两者都由D
继承?
如果我错过了什么,如何正确阅读以上规则。还是对于第一个问题,上述规则是否确实不清楚以至造成误解?
答案 0 :(得分:2)
...类对象S的虚拟成员函数C :: vf是最终重写器,除非其最派生的类S是基类子对象(如果有)声明或继承另一个重写的成员函数vf。
引用的规则可能有点误导,因此可能是有缺陷的。
仅对类型为vf
的任何基进行覆盖B
还是不够的,但是对于那基本子对象< / em>。在您的示例中,有两个类型为A
的基本子对象,其中一个被A::f
覆盖,另一个未被覆盖。
那么D继承哪个函数?还是两者都是D继承的?
两者都是继承的。