linux 虚函数调用性能,C++虚函数和多态

跟狄泰软件学院的唐老师学习C++已经有一段时间了,发现虚函数的概念一直不是很清楚,今天把唐老师的课程重新看了一下,先将相关知识点总结一下。

一、多态的概念

多态值通过类的指针(引用)调用类的方法时,根据实际的对象决定调用函数的具体目标。也就是说同样的调用语句在实际运行时有多种不同的表现形态。

二、多态的实现方式

C++ 直接支持多态的概念,通过使用virtual关键字对多态进行支持。被virtual声明的函数被子类重写后具有多态特性。被virtual声明的函数叫做虚函数。

三、示例一#include #include using namespace std;class Parent

{public:    virtual void print()

{        cout <

}

};class Child : public Parent

{public:    void print()

{        cout <

}

};void how_to_print(Parent* p)

{

p->print();     // 展现多态的行为}int main()

{

Parent p;

Child c;

how_to_print(&p);    // Expected to print: I'm Parent.

how_to_print(&c);    // Expected to print: I'm Child.

return 0;

}12345678910111213141516171819202122232425262728293031323334353637381234567891011121314151617181920212223242526272829303132333435363738

程序运行结果如下:

ad1ee02f4fca3652d3f41f559142b68c.png

上面代码中通过调用函数void how_to_print(Parent* p)来体现出多态性,虽然函数的参数都为Parent* p,但调用后的结果确不相同。下图为void how_to_print(Parent* p)函数执行流程:

8ab5e5aa7b2f1918894beaf3c2a4e76d.png

四、C++多态的实现原理

1.当类中声明虚函数时,编译器会在类中生成一个虚函数表;

2.虚函数表是一个存储成员函数地址的数据结构;

3.虚函数表是由编译器自动生成与维护的;

4.virtual成员函数地址会被编译器放入虚函数表;

5.存在虚函数表时,每个对象中都有一个指向虚函数表的指针,且放在类的最前面。

下图为虚函数调用流程:

c5f2adbb0c3c19063ba1e1b9eacfa79c.png

下面通过一个示例来说明:#include #include using namespace std;class Parent

{private:    int m_data;public:

Parent() : m_data(10)

{

}    virtual void print()

{        cout <

}

};class Child : public Parent

{public:    void print()

{        cout <

}

};struct Data {   // 模拟Child在内存中的分布

int *p;    int data;

};typedef void (*Fun)();int main()

{

Parent* c = new Child();

Data* data = (Data*)c;    cout <p: "<p <p): " <p) <data:" <data <

Fun fun = (Fun)(*(data->p));

fun();    return 0;

}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758591234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859

程序运行结果如下图所示:

c6ee476c500aba602d81acae31290a15.png

1.sizeof(Child): 8:表明Child除了一个继承自父类Parent的int m_data;成员变量所占用4字节之外,还多出了4字节。这4字节便用来存放虚函数表;

2.data->p: 0x404318:虚函数表地址;

3.data->data:10:打印出的是m_data对应的值,更进一步证明虚函数表是存储在类的最前面,占用4字节;

4.*(data->p): 4204792:虚函数表中存储的内容,是对应虚函数的入口地址,即void print()的入口地址。通过下一句的打印I'm Child.即可证明。

五、构造函数和析构函数能否声明为虚函数

1.构造函数不可能成为虚函数,因为在构造函数执行结束后,虚函数表指针才会被正确的初始化,所以在构造函数中不可能发生多态。

2.析构函数可以设计成虚函数。若发生继承关系时,父类的析构函数一定要实现为虚函数,否则若通过父类指针释放子类对象时无法调用子类的析构函数,会造成资源释放不完全。

3.析构函数中也不可能发生多态行为。因为在析构函数执行时,虚函数表指针已经被销毁,只能调用当前类中定义的版本。

1踩

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中的继承、多态虚函数是面向对象编程的重要概念。 继承是指一个类可以从另一个类继承属性和方法。子类可以继承父类的公有成员和保护成员,但不能继承私有成员。通过继承,子类可以重用父类的代码,并且可以添加自己的特定功能。继承可以实现代码的重用和层次化的设计。 多态是指同一个函数可以根据不同的对象调用不同的实现。多态可以通过虚函数来实现。虚函数是在基类中声明为虚拟的函数,它可以在派生类中被重写。当通过基类指针或引用调用虚函数时,实际调用的是派生类中的实现。这样可以实现动态绑定,即在运行时确定调用的函数。 虚函数的原理是通过虚函数来实现的。每个包含虚函数的类都有一个虚函数,其中存储了虚函数的地址。当调用虚函数时,编译器会根据对象的类型在虚函数中查找对应的函数地址并调用。 综上所述,C++中的继承、多态虚函数是实现面向对象编程的重要机制,它们可以提高代码的灵活性和可扩展性。 #### 引用[.reference_title] - *1* *3* [C++多态虚函数虚函数](https://blog.csdn.net/weixin_46053588/article/details/121231465)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [c++多态虚函数内部原理实战详解](https://blog.csdn.net/bitcarmanlee/article/details/124830241)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值