effective C++ 读书笔记 条款36-37
来源:程序员人生 发布时间:2014-12-24 08:42:18 阅读次数:2502次
条款36:绝不重新定义继承而来的non-virtual函数
重要点:non-virtual函数都是静态绑定
// 1241.cpp : 定义控制台利用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:
void func()
{
cout<<"Base::func()"<<endl;
}
};
class Derived : public Base
{
public:
void func()
{
cout<<"Derived::func()"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Derived test;
Base* pB = &test;
Derived* pD = &test;
pB->func();//调用Base::func()
pD->func();//调用Derived::func()
/*
这里我们讨论的不是关于隐藏的问题;上面pB指向1个子类,但是调用的是父类的func()函数,至于为何,由于不是虚函数,没有virtual;
要明白1点:non-virtual函数 Base::func and Derived::func都是静态绑定的,pB被声明为1个人 pointer-to-Base,通过pB调用的non-virtual
函数永久是Base所定义的版本,即便pB指向1个类型为它的派生类的对象。
pD 调用的是Derived的函数版本,这里也能够说成是隐藏,但是终究缘由是由于 静态绑定。
1般 Derived dTest,dTest.func()这样调用我们1般说是由于隐藏。对对象,而我们本例子当中对应的是指针或援用,是由于静态绑定!
*/
getchar();
return 0;
}
总上:任何情况下都不应当重新定义1个继承而来的non-virtual函数;
对1个基类来讲,如果1个函数定义为非虚函数,那末意味着这个函数其实不想改变,所以子类不应当继承它,1个类当中的非虚函数,不变性凌驾于其特异性上。
条款37:绝不重新定义继承而来的缺省参数值:
virtual函数是动态绑定,缺省参数值是静态绑定;
// 1240.cpp : 定义控制台利用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
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 color = Green) const
{
cout<<"Rectangle"<<endl;
}
};
class Circle : public Shape
{
public:
virtual void draw(ShapeColor color) const
{
cout<<"Circle"<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Shape* ps;
Shape* pc = new Circle;
Shape* pr = new Rectangle;
pr->draw();//这里调用的是Rectangle的draw函数,但是函数参数color却是Shape父类里面的参数
/*
virtual函数是动态绑定,而缺省参数值却是静态绑定。
这就出现了上面的 调用1个定义于子类的virtual函数,同时却使用base class为它所指定的缺省参数值。
pr的动态类型是Rectangle*,所以调用的是Ractangle的virtual函数,但是由于pr的静态类型是Shape*,所以此
函数调用的缺省参数值却是来自鱼Shape Class.
*/
getchar();
return 0;
}
总结:不要重新定义1个继承而来的缺省参数值,由于缺省参数值是静态绑定的,而virtual函数--你唯1应当覆写的东西--却是动态绑定!!
生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠