首页 > 代码库 > effective C++ 读书笔记 条款12与条款13

effective C++ 读书笔记 条款12与条款13

条款12:确定你的public继承塑膜出is-a关系:

这个条款主要将了一些特殊情况:比如企鹅是鸟,企鹅可以继承于鸟,但是鸟会飞,企鹅却不能飞;还有让正方形继承矩形可能也会造成这种尴尬!

这个问题以前想过,但是不知道怎么解决,如果现实生活当中确实要这么使用:比如 猫 狗 鱼  猪等等许多动物继承Animal类,但是猫狗等不会游泳,

假如这里是有很多动物,不能采用鱼里面专门加一个方法!  这个现在还没想出来,条款12也没有讲如果要这么用该怎么处理就是将要避免这样。

 

is - a;

在面向对象程序设计里面,ia - a指的是类的父子继承关系;

public继承就意味着 is - a ,适用于base - class 身上的每一件事情也一定适应于derived class身上。因此每一个子类对象也是一个父类对象。

 

条款13:避免遮掩继承而来的名称:

这个条款主要讲了遮掩继承,其实也就是我们经常说的 重载 重写(覆盖) 隐藏;下面就看一下 重载 重写 隐藏的区别:

1、重载的特征:在同一个类中;函数名字相同;参数不同;virtual 关键字可有可无。
2、重写(覆盖)特征是:分别位于派生类与基类;函数名字相同;参数相同;基类函数必须有virtual 关键字(这点非常要注意)。

关于隐藏:


 1、如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。
 2、 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与重写混淆)。

 

// 06.cpp : 定义控制台应用程序的入口点。///************************************************************************//* 目的:找出重载、重写、隐藏的区别	时间:2014年12月1日 19:06:03*//************************************************************************/#include "stdafx.h"#include <iostream>using namespace std;class Base{private:	int x;public:	virtual void mf1() = 0;	virtual void mf1(int) //重载,在同一个类当中或者说同一个工作区间内。	{		cout<<"调用基类的mf1函数"<<endl;	}	virtual void mf2()	{		cout<<"调用基类的mf2函数"<<endl;	}	void mf3()	{		cout<<"调用基类的mf3函数"<<endl;	}	void mf3(double)	{		cout<<"调用基类的mf3重载函数"<<endl;	}};class Derived:public Base{public:	virtual void mf1()	{		cout<<"调用子类的mf1函数"<<endl;	}	void mf3()	{		cout<<"调用子类的mf3函数"<<endl;	}	void mf4()	{		cout<<"调用子类的mf4函数"<<endl;	}};int _tmain(int argc, _TCHAR* argv[]){	Derived d;	int x;	d.mf1();//调用子类的mf1函数  这就是重写(覆盖)这是动态多态的最根本原因	//d.mf1(x);//error C2660: “Derived::mf1”: 函数不接受 1 个参数;	//虽然基类Base当中有mf1(int)函数,但是因为子类当中自己也有mf1()函数	//所以发生了隐藏	d.mf2();//这个没有任何问题,子类继承父类的函数,子类当中没有自己的mf2()函数,于是调用父类的函数	d.mf3();//调用子类的mf3()函数;这里基类当中的mf3()函数并没有virtual,但是调用的是子类的函数,说明子类的函数隐藏了父类的函数	// 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与重写混淆)。	//d.mf3(x);//error C2660: “Derived::mf3”: 函数不接受 1 个参数	//虽然基类当中有 mf3(double)函数,但是因为子类当中也有自己的mf3()函数	//所以发生了隐藏	/*	从d.mf1(x)和d.mf3(x)可以看出 virtual void mf1(int)与 void mf3(double),一个有virtual一个没有virtual	但是它们都发生了隐藏。	*/	getchar();	return 0;}


上面的代码应该很好的解释了三者的区别;在条款33里面说道如果不想子类隐藏父类的函数,那么在子类当中用using 声明式达到目标:

 

class Derived:public Base{public:		virtual void mf1()	{		cout<<"调用子类的mf1函数"<<endl;	}		using Base::mf1;	void mf3()	{		cout<<"调用子类的mf3函数"<<endl;	}	void mf4()	{		cout<<"调用子类的mf4函数"<<endl;	}};


 

 

 

 




 

effective C++ 读书笔记 条款12与条款13