为什么说c++不能重定义继承而来的默认参数
来源:互联网 发布:开淘宝店可以兼职吗 编辑:程序博客网 时间:2024/05/02 04:40
目前有许多文章都会详细介绍c++虚函数实现,博主在此稍微点题,从c++的虚函数实现,简单说明下为什么说不能重定义继承而来的默认参数
class Base{public: virtual void fun() { std::cout << "Base::fun()" <<std::endl; };};class Derive : public Base{public: virtual void fun() { std::cout << "Derive::fun()" << <<std::endl; };};int main(){ Base *d = new Derive; d->fun(); return 0;}
在上述代码中,d的虚函数表在编译器编译时,就被动态的替换为derive::fun() 。因此在d->fun()调用的时候就能调用到子类实现。
而这个与本次话题又有什么关系呢?在effecitve c++中的第37章有说到,绝不重现定义基础而来的缺省参数。
如果将上述的类声明改为
class Base{public: virtual void fun(int i = 1) { std::cout << "Base::fun, i = " << i <<std::endl; };};class Derive : public Base{public: virtual void fun(int i = 2) { std::cout << "Derive::fun , i = " << i <<std::endl; };};
大家猜测下实际的打印输出结果是什么呢?
答案是
Derive::fun , i = 1
为什么会出现这么诡异的输出呢,其实把上面的代码写成编译的伪代码大家就能知道原因了。
(*d->vptr[0])(d, 1);
vptr是编译器生成的虚函数表,在大多数编译器下都是在类的指针地址。而虚表带定义是由于每个编译器厂家按照自己的标准实现,c++标准中未做详细的规定,所以出现类指针的第一位不是虚表地址也不要奇怪。
在编译器生成虚表的时候,默认参数是由静态绑定,编译器把符合d的默认入参写入。就是说,默认参数在编译过程中就已经决定。
所以引用effective c++中的总结,virtual函数是你唯一覆盖的东西。
最后给大家再引申一个小问题,如果把上文中的
class Derive : public Base{public: virtual void fun(int i = 2) { std::cout << "Derive::fun , i = " << i <<std::endl; };};
改为
class Derive : public Base{private: virtual void fun(int i = 2) { std::cout << "Derive::fun , i = " << i <<std::endl; };};
那么请问,上段代码的编译结果是什么样子的,最后由什么样的输出呢?
答案还是输出Derive::fun,大家可以结合上面的编译器伪代码思考下。
博主的这篇博客可是参考effective c++和深度探索c++模型总结的,如果有不对的地方,欢迎大家在博客下留言指正,谢谢。
0 0
- 为什么说c++不能重定义继承而来的默认参数
- 避免对函数中继承得来的默认参数值进行重定义
- [effectiv c++]条款33:避免遮掩继承而来的名称(重载,重写,重定义)
- 《Effective C++》37: 绝不重新定义继承而来的缺省的参数值
- 《Effective C++》读书笔记之item37:绝不重新定义继承而来的缺省参数值
- Effective C++:条款37:绝不重新定义继承而来的缺省参数值
- 绝不要重新定义继承而来的缺省参数值(Effective C++_37)
- Effective C++:绝不重新定义继承而来的缺省参数值
- 读书笔记《Effective C++》条款37:绝不重新定义继承而来的缺省参数值
- C++之绝不重新定义继承而来的缺省参数值(37)---《Effective C++》
- 绝对不要重新定义继承而来的缺省参数
- 绝不重新定义继承而来的缺省参数值
- 绝不重新定义继承而来的缺省参数值
- 绝不重新定义继承而来的缺省参数值
- 不重新定义继承而来的缺省参数值
- 不要重新定义继承而来的缺省参数值
- 不要重新定义继承而来的缺省参数值
- 绝不重定义继承的函数默认参数
- Accurate, Dense, and Robust Multi-View Stereopsis论文分析与代码实现(一)
- 第二讲 Kali安全工具之top10
- A Sequence of Numbers (dp)
- 【codevs 1391】伊吹萃香
- 找出缺失的整数
- 为什么说c++不能重定义继承而来的默认参数
- Spark java程序入门(一)初始化spark
- javascript 中的正则表达式
- Tinker 热修复框架 简单上手教程
- 分析与设计(A&D)简介(2)
- matlab如何将矩阵数据转换成txt文件保存
- activemq 控制面板里Number Of Pending Messages、 Messages Enqueued等含义解释
- struts2框架的搭建及demo的简单实现
- unity 携程