[英]Virtual function calling a non-virtual function and vice versa
我有一个class A
作为 class 的基础class B
。
我在我的虚拟function, xyz()
中调用了非虚拟function, abc()
,如下所述。
由于运行时多态性, B:xyz
被调用——我理解这一点。
但是,我不明白,为什么后面跟着B:abc
而不是A:abc
,因为abc
是非虚拟 function。
请注意:我遇到了以下问题: Virtual function calling a non-virtual function 。 它提到在虚拟 function 中调用abc()
等效于this->abc()
,因此是 output。 但是,我不确定我是否理解这部分。
因为,当我做相反的事情(即非虚拟 function 调用虚拟函数)时,会显示正确的运行时多态性。 那么 this 指针会发生什么?
//Virtual function calling non-virtual
class A
{
public:
void abc()
{
cout<<"A:abc"<<endl;
}
virtual void xyz()
{
cout<<"A:xyz"<<endl;
abc();
}
};
class B: public A
{
public:
void abc()
{
cout<<"B:abc"<<endl;
}
void xyz()
{
cout<<"B:xyz"<<endl;
abc();
}
};
int main() {
A *obj3 = new B;
obj3->xyz();\
return 0;
}
Output
B:xyz
B:abc
//Non-virtual calling virtual function
#include <iostream>
using namespace std;
class A
{
public:
void abc()
{
cout<<"A:abc"<<endl;
xyz();
}
virtual void xyz()
{
cout<<"A:xyz"<<endl;
}
};
class B: public A
{
public:
void abc()
{
cout<<"B:abc"<<endl;
xyz();
}
void xyz()
{
cout<<"B:xyz"<<endl;
}
};
int main() {
A *obj3 = new B;
obj3->abc();
return 0;
}
Output
A:abc
B:xyz
Calls to your non-virtual abc
function are resolved, effectively, at compile time: so, when that is called from within another member function of class B
, the class B
version of the function is called, and is passed a pointer ( this
)到调用它的 object; 同样,如果从class class A
function 中调用,则将使用class A
定义。 也就是说,对于编译器,非虚拟函数与 class 相关联,而不是与 class 的任何特定实例相关联。
但是,编译器对虚拟xyz
function 的处理方式不同; 在这种情况下,对 function 的引用或指针被添加到 class 定义中(这通常被添加到所谓的vtable中,尽管细节是特定于实现的); 创建类的任何对象时,它们包括该 function 指针和/或 vtable 的副本。 当编译器看到调用这样一个虚拟 function 的代码时,它会通过适当的 function 指针将其转换为调用; so, the function 'travels with' the actual object: whether the function is called from the derived class or base class (in your code) is irrelevant – the function called is the one belonging to the object (instance) from which it is invoked .
总而言之:对非虚函数的调用在编译时被解析,而对虚函数的调用(在概念上)在运行时被解析。
要查看此“vtable”的实际创建,请尝试编译并运行以下代码:
#include <iostream>
class A {
public:
int i;
~A() = default;
void foo() { std::cout << i << std::endl; }
};
class B {
public:
int i;
virtual ~B() = default;
virtual void foo() { std::cout << i << std::endl; }
};
int main()
{
std::cout << sizeof(A) << std::endl;
std::cout << sizeof(B) << std::endl;
return 0;
}
这两个类之间的唯一区别是一个具有虚函数而另一个没有——但这会导致 class 对象的大小存在显着差异:vtable 的大小(可能带有一些“填充”以实现最佳对齐数据),(在我的 64 位 Windows 上,使用 MSVC,我得到的大小为 4 和 16。但实际值会因编译器和平台而异。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.