gpt4 book ai didi

c++ - 虚函数调用非虚函数,反之亦然

转载 作者:行者123 更新时间:2023-12-05 02:00:39 30 4
gpt4 key购买 nike

我有一个 class A 作为 class B 的基类。

我在我的虚拟函数xyz() 非虚拟函数abc(),如下所述。

由于运行时多态性,B:xyz 被调用——我理解这一点。

但是我不明白,为什么后面是B:abc而不是A:abc,因为abc是一个非虚函数。

请注意:我遇到了以下问题:Virtual function calling a non-virtual function .它提到在虚函数中调用 abc() 等同于 this->abc(),因此输出。但是,我不确定我是否理解这部分内容。

因为,当我做相反的事情时(即调用虚函数的非虚函数),会显示正确的运行时多态性。那么 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

最佳答案

非虚拟 abc 函数的调用在编译时有效地解析:因此,当它从另一个内部调用时class B 的成员函数,该函数的 class B 版本被调用,并被传递一个指向对象的指针 (this)它正在被调用;类似地,如果从 class A 函数中调用,则将使用 class A 定义。也就是说,对于编译器而言,非虚函数与类相关联,而不是类的任何特定实例。

但是,您的虚拟 xyz 函数在编译器中的处理方式不同;在这种情况下,函数的引用或指针被添加到类定义中(这通常被添加到所谓的 vtable 中,尽管细节是特定于实现的);当您的类的任何对象被创建时,它们都包含该函数指针和/或 vtable 的拷贝。当编译器看到调用此类虚函数的代码时,它会将其转换为通过适当函数指针的调用;因此,函数“与”实际对象一起“旅行”:函数是从派生类还是基类(在您的代码中)调用是无关紧要的——被调用的函数是属于对象的函数(实例)从中调用它。

总结:对非虚函数的调用在编译时解决,而对虚函数的调用(概念上)在运行时解决。

要查看此“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;
}

这两个类之间唯一的区别是一个有虚函数而另一个没有——然而这导致了类对象大小的显着差异:vtable 的大小(与,可能是一些“填充”以优化数据排列)! (在我的 64 位 Windows 上,使用 MSVC,我得到的大小为 4 和 16,但实际值会因编译器和平台而异。)

关于c++ - 虚函数调用非虚函数,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67065428/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com