38.绝不要又一次定义继承而来的缺省參数值。

又一次定义函数缺省參数值意味着又一次定义函数。而非虚函数不能又一次定义,所以将就考虑不能又一次定义虚函数的缺省參数值的原因:虚函数是动态绑定的而缺省參数值是静态绑定的。

静态类型是指程序中声明的类型,而动态类型是指实际对象的类型。举个栗子:

class A{
public:
virtual void fun(int a=0) const{cout<<a<<endl;}
}; class B:public A{
public:
virtual void fun(int a =2)const{cout<<a<<endl;}
};
int main(){
B* pb = new B();//pb的静态类型为 B*
A* pa = pb;//pa 的静态类型 为 A*,
//可是一个指针的静态类型不一定为其动态类型,如pa它的动态类型却是B类型的对象,这是由动态绑定实现的
pb->fun();
pa->fun();

虚函数是动态绑定的。但缺省參数值是静态绑定的,即对于pb,pa调用的虚函数,其使用的默认參数值都为静态绑定的,pa绑定的是 A类中的 a= 0,而pb绑定的是B类中的 a=2,两者不同。尽管函数都是调用B中动态绑定的虚函数,可是默认參数不同,输出结果也不同。

39.避免 ”向下转换“ 继承层次。

从一个基类指针到一个派生类指针称为向下转换,一般使用static_cast将基类指针强制转换为派生类指针。向下转换难看,easy导致错误。且难以理解,升级和维护。

向下转换的消除:使用虚函数调用来取代。第一种方法非常easy理解,可是对于一些类不适用,如基类范围太大导致7有些派生类不应该有这个函数的功能。所以要将这些类的每一个虚函数称为一个空操作。或者作为一个纯虚函数。并默认实现返回错误的操作。第二个方法是加强类型约束,使得指针的声明类型和你所知道的真的指针类型同样。

即对于用到这些向下转换时,通过一些设定。滤去那些不拥有真正指针类型的指针。仅仅留下须要进行操作的指针并以其真实的类型来调用其函数。

假设遇到必需要转换的情况,也不要使用static_cast,而是使用安全的用于多态的向下转换 dynamic_cast,当对一个指针使用dynamic_cast时,先尝试转换。假设成功返回一个合法的指针。否则返回空指针。

40.通过分层来体现”有一个“或”用..来实现“。

使某个类的对象成为还有一个类的数据成员。从而实现将一个类构筑在还有一个类之上,这个称为分层 Layering,也被称为构成,包括或嵌入。

对于有一个的概念非常easy理解,对于一个 Person, 有 Name,Address,Phone等属性,可是不能说Person是一个Name。

对于"用..来实现”,事实上就是调用其他类的对象作为类的主要数据成员,使用这个类的的函数接口来实现新的类中的功能与接口。

41.区分模版和继承。

依据依赖的类的用途来区分,如过依赖的类是类的行为,则为继承,如果依赖的类是类所操作的对象类型,则是模版。

如。企鹅类依赖于鸟类,鸟类中的接口决定的是企鹅类中的行为。即两者是继承关系,而当实现一个集合时,集合类依赖与类T,是因为类T为集合类的进行操作的对象。这是模版。

模版的实现会如果类能够调用T的构造析构赋值等函数。模版的特性是类模版的行为在不论什么地方都不依赖于T。行为不依赖于类型。

当对象的类型不影响类中函数的行为时,就使用模版来生成这样一组类。

当对象的类型影响类中函数的行为时。就用继承来得到这样一组类。

42.明智地使用私有继承。

私有继承不为 “是一个” 的关系。假设两个类之间的继承关系为私有继承,编译器一般不会将派生类对象转换为基类对象。私有继承时,基类的公有和protected 类型的成员都变成派生类的私有成员。私有继承意味着”用...实现“。私有继承纯粹是一种实现 技术。

私有继承仅仅是继承实现,而忽略接口。

私有继承在 软件 ”设计“过程中毫无意义,仅仅是在软件”实现“时才实用。

对于分层,也有 用...实现的含义,对于分层与私有继承,尽可能使用分层。必要时才使用私有继承。

而建议使用私有继承在用到保护成员和有虚函数介入时。

对于一个基类。仅仅作为其它类的实现来使用,使用分层作为其它类的私有成员。但其不是抽象类,导致其可能被其它人任意调用导致出错。这是就须要使用到私有继承。对于这样的具有实现可是仅仅能用于特定用途的基类。将其接口都改为protected类型。而正确使用它的类不用分层而使用私有继承来安全的使用基类。

对于模版,其为C++中最实用的组成部分之中的一个,可是,实例化一个模版,就可能实例化实现这个模版的代码,如构成set<int> 和set<double>的代码是全然分开的两份代码,模版会导致代码膨胀。改进的方法:创建一个通用类,储存对象的void*指针。创建还有一组类来保证类型安全使用通用类。以实现栈stack为例,先构建一个stack的通用类:

class GenericStack{
protected://实现类使用私有继承继承这个通用类,所以将接口保护起来
GenericStack();
~GenericStack();
void push(void* object);//使用指针
void* pop();
bool empty() const;
private:
struct StackNode{
void *data;
StackNode *next;
//在stack中使用指针来传递数据和保存数据,则节点析构时不用释放void指针指向的内存。
StackNode(void *newData,StackNode *nextNode)
:data(newData),next(nextNode){} };
StackNode *top;
GenericStack(const GenericStack&);//防止拷贝和赋值
GenericStack& operator=(const GenericStack&);
};

而要实现stack的详细类通过私有继承这个类来实现功能,并且能够使用模版来完美的完毕这个工作:

template <class T>
class Stack:private GenericStack{
public:
void push(T* objectPtr){GenericStack::push(objectPtr);}
T* pop(){return static_cast<T*>(GenericStack::pop());}
bool empty() const {return GenericStack::empty();}
};

这里使用私有继承。将通用类GenericStatck作为事实上现,而其接口函数都是内联函数,差点儿没有消耗,并且使用模版实现了类型安全的推断。对于创建随意类型的stack仅仅要又一次编译这个三个简单的内联函数就可以,而不是通用类中复杂的实现。极大的减少了程序的开销。

这种代码是令人惊叹的。近乎完美的。

首先使用了模版,编译器会依据你的须要来自己主动生成全部的接口。由于使用模版。这些类是类型安全的,类型错误会在编译期间就能发现。由于GenericStack的成员函数是保护类型,用户不可能绕过接口类来调用它。

由于这个模版的接口成员函数都被隐式的声明为内联。使用这些类时不会带来执行开销,生成代码就想用户直接使用GenericStack来编写的一样。由于GenericStack是使用void*指针,操作栈的代码仅仅须要一份。而不同类型仅仅要简单的编译类模版中的简单的内联函数即可。

简而言之,这个设计使代码达到了最高的效率和最高的类型安全。

Effective C++ 38-42的更多相关文章

  1. Effective Modern C++ 42 Specific Ways to Improve Your Use of C++11 and C++14

    Item 1: Understand template type deduction. Item 2: Understand auto type deduction. Item 3: Understa ...

  2. Effective C++ -----条款42:了解typename的双重意义

    声明template参数时,前缀关键字class和typename可互换. 请使用关键字typename标识嵌套从属类型名称:但不得在base class lists(基类列)或member init ...

  3. Effective Java 38 Check parameters for validity

    For public methods, use the Javadoc @throws tag to document the exception that will be thrown if a r ...

  4. 读书笔记 effective c++ Item 42 理解typename的两种意义

    1. class和typename意义相同的例子 问题:在下面的模板声明中class和typename的区别是什么? template<class T> class Widget; // ...

  5. 读书笔记 effective c++ Item 42 理解typename的两种涵义

    1. class和typename含义相同的例子 问题:在下面的模板声明中class和typename的区别是什么? template<class T> class Widget; // ...

  6. Effective C++ Item 42 了解 typename 的双重意义

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:声明 template 參数时,前缀keyword class 和 typename ...

  7. Effective C++ 条款42

    本节条款我们讨论一下class 关键字和typename关键字的不同以及对于模板函数(template function)的影响. 例如以下代码: template<class T> T ...

  8. Effective Java Index

    Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...

  9. AWR Report 关键参数详细分析

    WORKLOAD REPOSITORY report for DB Name DB Id Instance Inst num Startup Time Release RAC CALLDB 12510 ...

  10. Morris.js和flot绘制折线图的比较

    [文章摘要] 最近用开源的AdminLTE做框架感觉效果特别好,其针对图表库Morris.js和flot都提供了不错的支持,也都提供了这两者的例子.不过Morris.js是基于Raphael.js来的 ...

随机推荐

  1. 华为S5300系列升级固件S5300SI-V100R003C00SPC301.cc

    这个固件是升级V100R005的中间件,所以是必经的,注意,这个固件带有http的服务,但现在无论官网还是外面,几乎找不到这个固件的web功能,如果非要实现,可以拿V100R005的web文件改名为w ...

  2. Effective OC : 1-5

    1,了解Objective-C语言的起源: OC为C语言的超集,为C加入了面向对象的特性. 要理解C中的指针和内存模型. 2.在类文件里尽量少引入其它头文件: 引入过多头文件.将借口暴露,添加耦合度. ...

  3. C语言每日小练(四)——勇者斗恶龙

    勇者斗恶龙 你的王国里有一条n个头的恶龙,你希望雇佣一些骑士把它杀死(砍掉全部的头). 村里有m个骑士能够雇佣.一个能力值为x的骑士能够砍掉恶龙一个致敬不超过x的头,且须要支付x个金币. 怎样雇佣骑士 ...

  4. MVC之Ajax如影随行

    一.Ajax的前世今生 我一直觉得google是一家牛逼的公司,为什么这样说呢?<舌尖上的中国>大家都看了,那些美食估计你是百看不厌,但是里边我觉得其实也有这样的一个哲学:关于食材,对于种 ...

  5. 使用Bootstrap 3开发响应式网站实践01,前期准备、导航区域等

    "使用Bootstrap 3开发响应式网站实践"系列,将使用Bootstrap 3.2制作一个自适应网站,无论是在电脑.平板,还是手机上,都呈现比较好的效果.在电脑浏览器上的最终效 ...

  6. MVC自定义编辑视图,DateTime类型属性显示jQuery ui的datapicker

    实现的效果为:在编辑视图中,对DateTime类型的属性,显示jQuery UI的datepicker.效果如下: Student.cs public class Student    {       ...

  7. swing入门教程

    (转自http://terrificwanjun.bokee.com/) UI 组件简介 在开始学习 Swing 之前,必须回答针对真正初学者的一个问题:什么是 UI?初学者的答案是“用户界面”.但是 ...

  8. 解决hue报错:timed out (code THRIFTSOCKET): None

    报错栈: [/Jun/ :: +] decorators ERROR error running <function execute at 0x7fba2804ecf8> Tracebac ...

  9. Asp.Net Core App 部署故障示例 1

    相关阅读:Windows + IIS 环境部署Asp.Net Core App 1.  HTTP Error 502.5 – Process Failure 环境 Windows Server 201 ...

  10. unity 3D游戏场景转换

    //////////////////2015/07/07//////// /////////////////by xbw/////////////// ///////////////环境 unity ...