effective C++中条款37:绝不重新定义继承而来的缺省参数值

Effective C++ 条款37绝不重新定义继承而来的缺省参数值 深入解析 Effective C++ 条款37,揭示 virtual 函数动态绑定与缺省参数静态绑定之间的矛盾,理解为什么不应该重新定义继承而来的缺省参数值,以及 NVI 设计模式的应用。 阅读详情

virtual 函数会动态绑定,而virtual函数的缺省参数值是静态绑定的。用一个base类型的指针p去指向一个derived类对象,通过p调用虚函数时,会动态绑定到实际所指对象中的函数;用一个derived类型的指针p2指向一个derived对象,由p2调用函数时,直接就是调用的derived中的函数,其参数值也是derived类中函数对应的参数值。

#include <iostream>
using namespace std;
class A
{
public:
	enum Color {red,green,blue};
	A()
	{
		cout<<"Construct A"<<endl;
	}
	virtual void dodraw()
	{
		draw();
	}
private:	
	virtual void draw(Color color=blue) const
	{
		cout<<"base draw:"<<color<<endl;
	}
};
class B:public A
{
public:
	B()
	{
		cout<<"Construct B"<<endl;
	}
		virtual void dodraw()
	{
		draw();
	}

private:
	virtual void draw(Color color=red) const
	{
		cout<<"derived draw:"<<color<<endl;
	}
};
int main()
{
	B b;
	A *p=&b;
	B *p2=&b;
	p->dodraw();
	p2->dodraw();
	return 0;
}


上面的程序中,在B类中都重写了A中的两个virtual函数,从而,通过p和p2调用dodraw函数,其实都是调用的B中dodraw,而B中的dodraw函数调用B中draw函数,从而draw的实参就是B中的缺省实参:red

#include <iostream>
using namespace std;
class A
{
public:
	enum Color {red,green,blue};
	A()
	{
		cout<<"Construct A"<<endl;
	}
	virtual void dodraw()
	{
		draw();
	}
private:	
	virtual void draw(Color color=blue) const
	{
		cout<<"base draw:"<<color<<endl;
	}
};
class B:public A
{
public:
	B()
	{
		cout<<"Construct B"<<endl;
	}

private:
	virtual void draw(Color color=red) const
	{
		cout<<"derived draw:"<<color<<endl;
	}
};
int main()
{
	B b;
	A *p=&b;
	B *p2=&b;
	p->dodraw();
	p2->dodraw();
	return 0;
}


上面的程序,B和A中dodraw函数都是来源于A中,由p和p2调用dodraw时,都是调用的A类中的dodraw函数,dodraw再调用draw函数时,会动态绑定到实际所指的对象B中的draw函数,这在运行期确定,但draw函数的缺省实参是静态绑定的,就是A类中的blue值,这在编译器就已经确定。所以,如果重新定义继承而来的缺省参数值,会出现一种奇怪的现象:virtual函数用的derived类中的,而参数是用的base类中的。



量子密钥分发系统设计与实现(一):系统基本架构讨论 本文主要对量子密钥分发系统中的基础架构和基于系统的量子密钥协商过程进行了初步讨论,为后期系列文章进行铺垫。 阅读详情

相关推荐

使用Simulink对基于GaN器件的高频电源进行建模与仿真,重点在于优化其效率

本文介绍了基于Simulink的GaN器件高频电源仿真建模方法。通过7个步骤详细讲解系统构建过程:从创建模型、设置电源、配置GaN开关网络,到添加磁性元件、负载和控制器设计,最后进行仿真分析。重点探讨了效率优化策略,包括开关频率选择、磁性元件优化、散热设计改进及控制策略调整。该教程为GaN器件在电力电子系统中的应用提供了完整的仿真流程指导,有助于设计人员验证方案并优化性能。

amy_mhd的博客 207

条款37绝不重新定义继承而来的缺省参数值

条款37绝不重新定义继承而来的缺省参数值内容:     审视了一下条款以后,我们可以换一种说法:绝不重新定义继承而来的virtual函数或non-virtual函数的缺省参数值.而在上一款中我们提到,绝对不要试图去重新定义继承而来的non-virtual函数,将这句话与本条款合并的话,我们就可以将本条款的内容简化为:绝不重新定义继承而来的virtual函数的缺省参数值.为什么继承而来的vir

scofieldzhu的专栏 2369

基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目)

基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目),本资源中的源码都是经过本地编译过可运行的,评审分达到98分,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、毕业设计、期末大作业和课程设计使用需求,如果有需要的话可以放心下载使用。基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目)基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目)基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目)基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目)基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目)基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目)基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目)基于Python+Django的在线音乐网站设计与实现源码+数据库(毕业设计项目)基于Python+Django的在线音乐网站设计与实现源码

绝不重新定义继承而来的缺省参数值

序言 这里我们必须明白public 继承就是is a 关系,默认子类就是父类,虽然子类有自己新添加的功能,但是基于里氏代换原则,能用到父类的地方也能间接的应用到子类。也就意味着如果保持代码干净性,父类的non-virtual 函数(子类的公有特性提取),如果该函数有变动,可以考虑设为虚函数或者继承原有的non-virtual,子类再重新添加新函数对原有继承进行修改,这样是为了确保不要重新定义继承而...

liunanya的博客 394

Effective C++条款37绝不重新定义继承而来的缺省参数值(Never redefine a function‘s inherited default parameter value)

Effective C++条款37绝不重新定义继承而来的缺省参数值(Never redefine a function‘s inherited default parameter value)

CltCj的博客 562

绝不重新定义继承而来的缺省参数值——条款37

让我们一开始就将讨论简单化。你只能继承两种函数:virtual和non-virtual函数。然而重新定义继承而来的non-virtual函数永远是错误的(见条款36),所以我们可以安全地将本条款的讨论局限于“继承一个带有缺省参数值的virtual函数”。 这种情况下,本条款成立的理由就非常直接而明确了:virtual函数系动态绑定(dynamically bound),而缺省参数值却是静态绑定(statically bound)。 对象的所谓静态类型(st...

yj_android_develop的博客 395

effective C++》:条款37——绝不重新定义继承而来的缺省参数值

引子: 阿里的一道题: 1 #include <IOSTREAM> 2 using namespace std; 3 4 class A{ 5 public: 6 virtual void func(int val = 0) 7 { 8 cout<<"a~"<<val<&lt...

anjl1296的博客 146

Effective C++条款37:绝不重新定义继承而来的缺省参数值

考虑以下类: class Shape { public: enum ShapeColor{Red, Green, Blue}; virtual void draw(ShapeColor color = Red) const = 0; ... }; class Rectangle:public Shape { public: virtual void draw(ShapeColor colo...

qq_44800780的博客 238

Effective C++》读书笔记 条款37绝不重新定义继承而来的缺省参数值

我们都知道virtual函数是动态绑定的,那么为什么要求绝不重新定义继承而来的缺省参数值呢?先来看一个例子 class Shape { public: enum ShapeColor{Red,Green,Blue}; //纯虚函数,因为所有形状都必须提供一个函数,用来绘出自己,而且每个形状都不一样 virtual void draw(ShapeColor color = Red)const ...

junya_zhang的博客 347

Effective C++条款37继承与面向对象之(绝不重新定义继承而来的缺省参数值

待续

董哥的黑板报 779

Effective C++条款37绝不重新定义继承而来的缺省参数值

由于重新定义继承而来的non-virtual函数是不正确的(见上一个条款),所以这个条款就将问题局限于:绝不重新定义继承一个带有缺省参数值的virtual函数。 (一) virtual函数是动态绑定的,而缺省参数却是静态绑定。  对象的所谓静态类型,是它在程序中被声明时所采用的类型。 你可能会在“调用一个定义于derived class 内的virtual函数”的同时,却使用了ba

u010470972的专栏 929

Effective C++条款37继承与面向对象——绝不重新定义继承而来的缺省参数值

前言 在条款36介绍过,在继承体系中,派生类最好只重写覆盖virtual函数,而不要去隐藏基类的non-virtual函数 因此,本条款要介绍的“不要重新定义继承而来的缺省参数值”,是针对于virtual函数而言的 一个重要的概念:virtual函数是动态绑定的,而virtual函数的缺省参数值却是静态绑定的 一、静态类型、动态类型 静态类型:在被声明时所采用的的类型 动态类型:目前所知对象的类型 演示案例 下面是一个继承体系 class Shape { public: enum

www_dong的博客 199

读书笔记《Effective C++条款37绝不重新定义继承而来的缺省参数值

virtual函数系动态绑定,而缺省参数值却是静态绑定。

Do-Program的专栏 352

effective C++ 条款 37绝不重新定义继承而来的缺省参数值

effective C++ 条款 37绝不重新定义继承而来的缺省参数值 重新定义一个继承而来的non-virtual函数永远都是错误的,本条款的讨论限制在“带有缺省参数的virtual函数”。 virtual函数是动态绑定的,而缺省参数却是静态绑定。 对象的所谓静态类型,是它在程序中被声明时所采用的类型。 class Shape { public:     enum ShapeColor {...

DreamHigh 192

Effective C++ 条款37解读:绝不重新定义继承而来的缺省参数值(2012年某公司笔试试题)

下面, 我们来看一个简单但容易出错的题目: #include using namespace std; class A { public: virtual void fun(int n = 1) { cout " << n << endl; } }; class B : public A { public: virtual void fun(int n = 2) { cout "

认知 行动 坚持 7445

Effective C++条款 37绝不重新定义继承而来的缺省参数值

重新定义一个继承而来的non-virtual函数永远都是错误的,本条款的讨论限制在“带有缺省参数的virtual函数”。 virtual函数是动态绑定的,而缺省参数却是静态绑定。对象的所谓静态类型,是它在程序中被声明时所采用的类型。   #include "StdAfx.h" #include using namespace std;     class Shape {

~~程序是门艺术,而我却在艺术之门之外~~ IT草根专栏 462

Effective C++条款 37绝不重新定义继承而来的缺省参数值

我们都知道虚函数的调用是动态绑定的,但是,对于虚函数中的默认参=参数的值确实静态绑定的,什么意思? 见代码: 一个表示形状的类,其中颜色可以是默认的参数也可以是自主选择的颜色。对于以下的继承体系而言 考虑如下的多态使用方式: 这时将会出现问题了,对于Retangle,我们对其虚函数draw指定的默认参数为Green,但是如果我们用多态的方式去调用draw函数。 这时 draw() 函数将会调用基类中的默认参数,因为对于虚函数的默认参数是动态绑定的,这样可以提高编译期运行效率。 所以我们对于虚函数的默认

qq_44664843的博客 216

Effective C++条款37绝不重新定义继承而来的缺省参数值

要点: 绝对不要重新定义一个继承而来的缺省参数,因为缺省参数都是静态绑定,而virtual函数――你唯一应该覆写的东西――却是动态绑定。     virtual函数是动态绑定的,而缺省参数却是静态绑定,对象的所谓静态类型,是它在程序中被声明时所采用的类型。 class Shape { public: enum ShapeColor {Red, Green, B...

weixin_34192993的博客 76
上一篇: C/C++中volatile关键字详解
下一篇: 函数重载之const
THEALVA
博客等级 码龄15年 14粉丝 36原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值