当中间 类 跳过实现时,在继承层次结构中执行哪个虚方法?
Which virtual method is executed in an inheritance hierarchy when intermediate classes skip the implementation?
我确定之前有人问过这个问题,但我只是不知道要搜索什么。因此,一旦有人向我指出类似问题,我很乐意删除此问题。如果有人有更好的建议,我也很乐意重命名问题:-)
我想知道以下代码是否是标准定义的行为,或者这是否可能 compiler/platform 依赖:
struct A
{
virtual void f()
{
std::cout << "A::f()" << std::endl;
}
};
struct B : public A
{
// f() is not implemented here
};
struct C : public B
{
virtual void f() override
{
B::f(); // call f() of direct base class although it is not implemented there
std::cout << "C::f()" << std::endl;
}
};
int main()
{
A* pA = new C();
pA->f();
}
Visual Studio 2017 和 gcc 5.4.0 的输出是:
A::f()
C::f()
编译器是否会在层次结构中向上搜索直到找到实现?你能link达到C++标准吗?我通过在纯虚拟中制作 f() 来测试它, linker 很好地告诉我有一个未解析的符号。我可以依靠它吗?
据我所知,使用像 B::f() 这样的范围运算符总是调用非虚拟版本。所以永远不会发生多态性,是吗?
编辑:误导的打印语句,将 "B::f()" 替换为 "C::f()"。
指针的动态类型
A* pA = new C();
是C *
。
所以调用了classC中的虚函数
struct C : public B
{
virtual void f() override
{
B::f(); // call f() of direct base class although it is not implemented there
std::cout << "B::f()" << std::endl;
}
};
classB并没有重新定义基classA的虚函数。所以在这个语句中
B::f(); // call f() of direct base class although it is not implemented there
调用了classA中定义的虚函数。即table的虚函数指针classB包含了classA中定义的函数的地址。
在本次通话中
B::f();
可以访问 class B 的虚函数 table 并且这个 table 包含 class A 中函数定义的地址,因为class B.
中的函数未被覆盖
来自 C++ 标准(5.2.2 函数调用)
- ...If the selected function is non-virtual, or if the id-expression in the class member access expression is a qualified-id, that function
is called. Otherwise, its final overrider (10.3) in the dynamic type
of the object expression is called; such a call is referred to as a
virtual function call. [
我确定之前有人问过这个问题,但我只是不知道要搜索什么。因此,一旦有人向我指出类似问题,我很乐意删除此问题。如果有人有更好的建议,我也很乐意重命名问题:-)
我想知道以下代码是否是标准定义的行为,或者这是否可能 compiler/platform 依赖:
struct A
{
virtual void f()
{
std::cout << "A::f()" << std::endl;
}
};
struct B : public A
{
// f() is not implemented here
};
struct C : public B
{
virtual void f() override
{
B::f(); // call f() of direct base class although it is not implemented there
std::cout << "C::f()" << std::endl;
}
};
int main()
{
A* pA = new C();
pA->f();
}
Visual Studio 2017 和 gcc 5.4.0 的输出是:
A::f()
C::f()
编译器是否会在层次结构中向上搜索直到找到实现?你能link达到C++标准吗?我通过在纯虚拟中制作 f() 来测试它, linker 很好地告诉我有一个未解析的符号。我可以依靠它吗?
据我所知,使用像 B::f() 这样的范围运算符总是调用非虚拟版本。所以永远不会发生多态性,是吗?
编辑:误导的打印语句,将 "B::f()" 替换为 "C::f()"。
指针的动态类型
A* pA = new C();
是C *
。
所以调用了classC中的虚函数
struct C : public B
{
virtual void f() override
{
B::f(); // call f() of direct base class although it is not implemented there
std::cout << "B::f()" << std::endl;
}
};
classB并没有重新定义基classA的虚函数。所以在这个语句中
B::f(); // call f() of direct base class although it is not implemented there
调用了classA中定义的虚函数。即table的虚函数指针classB包含了classA中定义的函数的地址。
在本次通话中
B::f();
可以访问 class B 的虚函数 table 并且这个 table 包含 class A 中函数定义的地址,因为class B.
中的函数未被覆盖来自 C++ 标准(5.2.2 函数调用)
- ...If the selected function is non-virtual, or if the id-expression in the class member access expression is a qualified-id, that function is called. Otherwise, its final overrider (10.3) in the dynamic type of the object expression is called; such a call is referred to as a virtual function call. [