C++基础(五)虚函数、重载、覆盖、隐藏 虚函数总是跟多态联系在一起,引入虚函数可以使用基类指针对继承类对象进行操作!虚函数:继承接口(函数名,参数,返回值),但是实现不继承(函数体)

非虚函数:继承接口,也继承实现;

1)虚析构函数(当一个类打算作为基类使用时候,其析构函数必须是虚函数)

构造函数可以为虚函数吗? 不可以,在生成对象的时候,必须向编译器明确指定要生成什么类型的对象,因而不存在虚函数的问题;只有当对象已经存在,我用什么接口去操作它的问题;

例子:

class A{public:A();virtual~A();};class B: public A{public: B();~B();};int main(){A *pA=new B; //调用B的构造函数delete pA; return 0; }

这里通过指针A去调用B类的析构函数,但是如果 ~A()不是虚析构函数,就不存在多态,就会去调用A中的析构函数,最后结果可能是B对象中的A成分被析构了,其他 还残留;所以当一个类作为基类时候,其析构函数必须是虚函数,这样防止出现析构不完全的情况;

2)当虚函数出现在构造、析构函数中时(即在构造函数中调用虚函数),函数退化为普通函数。为什么? <>中条款

例子:(转自<>中条例9)

class Transaction

{public:Transaction();virtual void LogTransaction() const = 0;// ...};Transaction::Transaction(){// ...LogTransaction();}class BuyTransaction : public Transaction

{public:virtual void LogTransaction() const;// ...};

这里调用BuyTransaction的构造函数,因为BuyTransaction是继承类所以先调用基类的构造函数,此时派生类独有的那部分还未初始化,<>中这么解释:“这个对象内的BuyTransaction成分还未初始化,最安全的办法是当他不存在,对象在derived成分还未初 始化时该对象不会成为一个derived对象”所以Transaction 的构造函数会调用基类的 LogTransaction() const;而且此处是个纯虚函数,会报错

3)虚函数与覆盖,重载,隐藏

重载首先出现在非继承关系当中,当同一个类中,两个函数的参数不同,名字相同,返回值类型无所谓(函数返回值不作为重载的参考,因为函数调用时候不出现返回值);

注意两个函数可以仅仅因为const与非const的差别来实现重载;

虚函数与覆盖均出现在一个继承体系中,覆盖针对的是普通函数,当父类子类中出现同名(相同返回值,相同参数,相同函数名)要求绝对一致

虚函数在父类子类中,首先在父类中声明该函数为virtual,那么子类可以重新定义该函数的实现,这里主要涉及多态,就是覆盖的情况加上virtual,通过指针或者引用实现多态;

隐藏显得简单粗暴,在继承类中只要出现于父类同名(只要求同样的函数名/变量名,其他返回值,virtual 非virtual不管)的函数,则用对象调用同名函数时候,基类对应的同名函数、变量隐藏,如果要访问其父类的同名成员应该明确使用 基类名::成员来访问;

例子:

class A{public:virtual ~A(){};void process(int i,char c); //重载,编译期间即可确定该调用哪个函数char process(double d,int c); //只要函数名相同,返回无所谓,参数不同void process(int i); void process(int i)const; // 此处相当于void process(const A *this,int i);void process(consttint i); //这里仅仅因为const属性不同即可实现重载virtual int foo(int, char){...}; int foo2(){};void foo3(int,int ){};}class B: public A{public:int foo(int ,char){...}; //虚函数,这里函数接口要严格一致(大部分编译器要求返回值也要一致)int process(){...}; //隐藏基类函数 int foo2(){}; // 这里不含虚属性,会覆盖int foo3(){return 0;}; //会隐藏A类的foo3}int main(){B b;A *pA=&b;pA->foo2(); //这里调用A类的foo2();不涉及多态;pA->foo(3,'c'); //B类foo() 涉及多态}

总结:

1)覆盖与虚函数是一对兄弟,要求函数的返回值,函数名,参数严格一致,虚函数是覆盖加上virtual的情况;

2) 隐藏是覆盖的推广,覆盖是隐藏的特例,只要求函数名一样,其他不管,在继承体系中,子类的同名函数会将父类的同名函数隐藏;

3)当使用指针时候,指向基类的指针会根据实际对象的类型,选择相应的虚函数执行,如果派生类没有重新定义基类的虚函数,那么依然执行基类的虚函数;

4)当不存在虚函数的情况下,使用基类的指针,不会下降到派生类中去搜索函数;所以virtual属性相当于告诉基类指针:当执行我时,请到相应对象中搜索对应的虚函数;

5)纯虚函数所在的类是抽象类,不能实例化,定义了纯虚函数意味着这个函数只能为父类,其负责定义接口而不负责实现;

6)当使用对象来调用相应的函数时候,主要考虑的是对基类同名函数的隐藏(包括覆盖),而不需要考虑多态;

7)注意构造析构函数中不能调用虚函数,当执行派生类的构造函数时候,先构造的是其基类成分,再执行派生类成分的构造,虚函数此时无意义;

8)c++是个细节非常多,非常复杂的语言。

更多内容,欢迎关注我的公众号:无情剑客

c++ public 函数名相同_C++虚函数、重载、覆盖相关推荐

  1. java 析构函数_C++虚函数

    码字不易,欢迎给个赞! C++虚函数是多态性实现的重要方式,当某个虚函数通过指针或者引用调用时,编译器产生的代码直到运行时才能确定到底调用哪个版本的函数.被调用的函数是与绑定到指针或者引用上的对象的动 ...

  2. C++ 虚函数成员和纯虚函数

    一般虚函数成员的声明语法是: virtual 函数类型 函数名(形参表); 在类的定义使用virtual关键字来限定成员函数,虚函数声明只能出现在类定义中的函数原型声明中,而不能在成员函数实现的时候出 ...

  3. c++ 虚函数多态、纯虚函数、虚函数表指针、虚基类表指针详解

    文章目录 静态多态.动态多态 虚函数 哪些函数类型不可以被定义成虚函数? 虚函数的访问方式 析构函数中的虚函数 虚函数表指针 vptr 多继承下的虚函数表 虚基类表指针 bptr 纯虚函数 抽象类 虚 ...

  4. 析构函数可以为纯虚函数吗?纯虚函数可以有函数体吗?纯虚函数需要函数体吗?

    先回答标题中中的几个问题: 析构函数可以为纯虚函数吗? yes. 纯虚函数可以有函数体吗? yes. 纯虚函数需要函数体吗? 一般来讲,如果析构函数是纯虚函数,那么析构函数必须要有函数体,如果是其它函 ...

  5. C++之指针探究(十一):函数名的本质和函数指针

    相关博文:C++之指针探究(十三):函数指针数组 相关博文:C++之指针探究(十二):指针.下标.数组及其作函数参数探究 相关博文:C++之指针探究(十一):函数名的本质和函数指针 相关博文:C++之 ...

  6. 为什么静态static成员函数不能成为virtual虚函数

    首先什么是static静态成员函数?静态成员函数不属于类中的任何一个对象和实例,属于类共有的一个函数.也就是说,它不能用this指针来访问,因为this指针指向的是每一个对象和实例. 对于virtua ...

  7. linux打印函数名,linux kernel 打印函数指针对应的函数名方法

    linux kernel 打印函数指针对应的函数名方法 内核中函数指针用的很多,在debug 的时候能直接打印出一个函数指针对应的函数就会很方便. 打印裸指针(raw pointer)用 %p,%p除 ...

  8. 虚函数,虚函数表,虚函数实现原理,虚函数实现机制,虚函数解决的问题

    虚函数 虚函数表 虚函数实现原理? 虚函数解决的问题?虚函数解决问题的实现机制? 虚函数模型的构建? 虚函数模型的应用?

  9. 函数名地址、函数名取地址、函数名解引用问题

    以下,转载自http://blog.sina.com.cn/s/blog_6aafe9c90100xg2y.html 对一个函数进行 如下操作: 1.函数名地址 2.函数名取地址 3.函数名解引用 它 ...

最新文章

  1. 【LaTeX】E喵的LaTeX新手入门教程(2)基础排版
  2. Struts2配置struts.xml文件
  3. OpenCV转换PyTorch分类模型并使用OpenCV C ++启动
  4. 延时消息_手把手实现一条延时消息
  5. 量子计算机 模拟,新量子算法将量子模拟器变成量子计算机,可以进行量子计算...
  6. 让我们共同怀揣文学与艺术的梦想
  7. JS中的间歇(周期)调用setInterval()与超时(延迟)调用setTimeout()相关总结
  8. 微型计算机主存可以分为,计算机基础试题 (含答案)
  9. 六、Python第六课——Python中的for循环及数字列表
  10. 混合列压缩(HCC)在OLAP及OLTP场景中的测试
  11. 停止使用C#异步流保存到磁盘
  12. java io流屏幕输出_java IO流 之 输出流 OutputString()的使用
  13. 物联网应用层安全威胁_物联网安全国家标准发布,物联网安全产业链确立
  14. 2010年经典语录,我们全OUT了
  15. SpringCloud注册中心集群化及如何抗住大型系统的高并发访问
  16. linux替换字符串 正则,Linux 字符串操作-裁剪和正则替换
  17. android配置网络权限管理,Android 网络权限配置
  18. 【IT互联网系列】什么是网关?网关的作用是什么?看完不懂,你捶我
  19. OpenFaceswap 入门教程(1):软件安装篇
  20. python实现连环阵

热门文章

  1. 『震惊』秘密报告披露转基因食品危害
  2. 学网络编程很好的参考源码
  3. 女生最想让男生知道的58件事[[急转]]
  4. 2019北妈和你:活着就意味必须要做点什么,请好好努力
  5. 曝光:一位来自微软公司的粉丝 写给我的信
  6. 干得最多最累,工资还不如新人
  7. 经典面试题(50):以下代码将输出的结果是什么?
  8. Adobe illustrator 多个对象进行环形布局 - 连载22
  9. 内蒙古农大孙志宏教授证实超深度混合宏基因组测序能够对人类肠道微生物组中的低丰度物种进行基因组和功能表征...
  10. 这份精子保存了1亿年,不仅长度惊人还刷新了一项记录