提到虚函数,我们就会自然而然的想到多态,但是当虚函数中存有默认参数值的时候,在派生类中重定义这个虚函数时不可以改变这个参数的值。

请看下面的例子:

#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:Base(){std::cout << "Base Constructor" << std::endl;}virtual ~Base(){std::cout << "Base Destructor" << std::endl;}public:virtual void g(int a, int b = 10)   //虚成员函数,带有一个默认参数值10{cout << "Base" << a << " " << b << endl;}protected:std::string Bmsg;
};class Derive : public Base
{
public:Derive(){std::cout << "Derive Constructor" << std::endl;}~Derive(){std::cout << "Derive Destructor" << std::endl;}public:void g(int a, int b = 5)     //继承基类的虚函数,但是将默认参数值改变成了5{cout << "Derive" << a << " " << b << endl;}private:std::string Dmsg;
};int main()
{Base * pb = new Derive;std::cout << std::endl;pb->g(1);      //调用虚函数 cout << endl;delete pb;pb = NULL;return 0;
}

和我们预想的一样,编译器调用了派生类的虚函数,但是输出的结果应该是5才对,为什么会输出10呢?

我们知道,pb指针是动态绑定的,即需要调用哪个作用域的函数需要看程序运行到那个时刻它指向的是什么,本例中pb指向派生类,所以会调用派生类的g函数。

但是函数的参数却是静态绑定的,它不会因为pb指向的类型的改变而改变,换句话说,我们定义pb的时候指定它的类型是Base*,是基类指针,所以函数的默认参数绑定的是基类的默认参数值,不会因为它指向的是派生类而改变。

所以无论如何,不要在派生类中改变虚函数的默认参数值。

C++学习笔记-----永远不要在派生类中改变虚函数的默认参数值相关推荐

  1. C++学习笔记-----不要在构造函数和析构函数中调用虚函数

    考虑下面的程序: #include <iostream> using namespace std;class Base { public:Base() { cout << &q ...

  2. C++类中的虚函数不能为模板函数

    C++类中的虚函数不能为模板函数 首先,理解模板的原理.例如,定义了一个模板函数: template<typename A> void Func(const A& a) {    ...

  3. C/Cpp / 模板类中可以使用虚函数吗?模板成员函数可以是虚函数吗?

    一.答案 前者是可以的,后者是不可以的. #include <iostream>template <class T> class Base { public:virtual v ...

  4. 模板类中使用友元函数的方式,派生类友元函数对基类的成员使用情况

    在一般友元函数的前面加上 template<typename T),注意在函数的声明和定义处都要加这个模板 例如: //模板类,长方体类 template <typename Elemen ...

  5. 基类成员的public访问权限在派生类中变为_第17篇:C++继承中虚表的内存布局

    我们已经表明,非虚类的对象实例不包含虚指针,编译器在编译阶段也没有为非虚类没有构建虚表.而本篇我们会从简单的单继承链分析虚类中虚表构造过程和内存布局.这一切假定你有如下基础 对gdb调试器使用有一个比 ...

  6. 避免在派生类中重新定义基类的非虚函数

    我们都知道,在基类中定义虚函数的目的是允许派生类拥有相同接口却可以有不同的实现,通过对象的指针或引用来访问虚函数可以实现运行时的多态.这么说来,在派生类中重定义(override)虚函数是没有任何问题 ...

  7. Kotlin 学习笔记(八)—— Kotlin类与对象之接口

    Kotlin 学习笔记(八)-- Kotlin类与对象之接口 Kotlin学习笔记系列教程 Kotlin 学习笔记(一)-- 概述.学习曲线.开发工具.参考资料 Kotlin 学习笔记(二)-- 基础 ...

  8. Python学习笔记(九):类和对象

    Python学习笔记(九):类和对象 关于类和对象 Python学习笔记(九):类和对象 一.类和对象 类的定义 类的实例化 类对象的使用 二.self用法 三.类方法 实例方法 类方法 静态方法 静 ...

  9. 基类数组存放派生类_永远不要将派生类数组赋值给基类类型指针

    C.152: Never assign a pointer to an array of derived class objects to a pointer to its base C.152:永远 ...

最新文章

  1. 中端存储不能承受之重
  2. 3.2.1 虚拟内存的基本概念
  3. 《JavaScript权威指南》学习笔记——Day2
  4. 图书推荐(持续更新)
  5. 2.oracle物理结构,oracle实验2oracle物理结构管理
  6. 使用蓝图构建Flask项目目录
  7. 4. 怎么在生活中提升专注力?
  8. Unity中UI界面颤抖解决方法
  9. assert()和panic()
  10. UT-Exynos4412开发板三星ARM四核旗舰开发平台android4.0体验-11有线网络功能调试
  11. CAD文件版本怎么转换?如何将高版本转换成低版本?
  12. nyistOJ-See LCS again(二分)
  13. hdu 5175 Misaki's Kiss again (抑或运算+公式变形)
  14. ‘settings.xml’ has syntax errors less… 和Parent ‘org.springframework.boot’has problems less…的问题解决
  15. “2012年全国职业院校技能大赛”高职组信息安全管理与评估赛项获奖名单
  16. 学习WEB前端开发是选择自学还是去培训机构?
  17. J-Link连上电路板,keil检测不出MCU
  18. Android开发笔记(五十九)巧用传感器
  19. excel高级筛选_Excel自动筛选还是高级筛选?
  20. 维普计算机研究与发展,计算机研究与发展杂志

热门文章

  1. Java多线程-线程中止
  2. [BZOJ3932][CQOI2015]任务查询系统(差分+主席树)
  3. scrapy two
  4. 7月14号day6总结
  5. 洛谷P3195 [HNOI2008]玩具装箱TOY
  6. 操作系统概念学习笔记 15 内存管理(一)
  7. 直接用img 的src属性显示base64转码后的字符串成图片【原】
  8. UltraEdit常用配置搭建Java/C开发环境
  9. 迪杰斯特拉--- 模板(求最短路径/输出路径/所有路径都可以走的做法)
  10. 牛客网(剑指offer) 第十八题 二叉树的镜像