Effective C++ 5.实现

//条款26:尽量延后变量的定义式出现的时间
//	1.不仅应该延后变量的定义,更应该直到使用该变量的前一刻为止,甚至应该尝试延后这份定义直到能够给它初始值为止。如果这样,不仅能够避免构造和析构的非必要操作,还可以避免毫无意义的调用默认构造函数带来的开销。

//条款27:尽量少做转型动作
//	1.尽量以C++风格的转型替代C风格的转型,前者更加安全。
//	2.const_cast 通常用来将对象的常量性转除(cast away the constness)。它是唯一有此能力的C++-style转型操作符。
//	3.dynamic_cast用来执行继承体系中安全的向下转型或跨系转型动作。也就是说你可以利用它将指向基类对象的指针或者引用转型为指向派生类对象的指针或引用,并得知转型是否成功。如果转型失败,
//		会以一个null指针(当转型对象是指针)或一个exception(当转型对象是引用)表现出来。dynamic_cast是唯一无法由旧式语法执行的转型动作,也是唯一可能消耗重大运行成本的转型动作。
//	4.static_cast 基本上拥有与C旧式转型相同的威力与意义,以及相同的限制。例如将一个非 const 的对象转换为 const 对象,或将int 转换为 double等等。它也可以用来执行上述多种转换的反向转换,
//		例如将void*指针转为typed指针,将pointer-to-base转为pointer-to-derived。但是他无法将const转为non-const,这个只有const-cast才能够办到。
//	5.reinterpret_cast意图执行低级转型,实际动作及结果可能取决于编译器,这也就表示它不可移植。例如将一个pointer to int 转型为int。这一类转型在低级代码以外很少见
//dynamic     英 [da??næm?k]       美 [dai?næmik]       adj.动态的
//reinterpret 英 [?ri:?n?t?:pr?t]  美 [?ri:?n?t?:rpr?t] vt. 重新解释
class CFather
{
public:
	CFather(){}
	virtual ~CFather(){}

	virtual void Fun(){printf("Father\n");}
};
class CChild : public CFather
{
public:
	virtual void Fun(){printf("Child\n");}
};
{
	CChild Child;
	CFather *pFather = dynamic_cast<CFather*>(&Child);
	pFather->Fun();	//输出Child

	CFather Father;
	CChild *pChild = dynamic_cast<CChild*>(&Father);	//pChild = 0x00000000
}
{
	CChild Child;
	CFather *pFather = static_cast<CFather*>(&Child);
	pFather->Fun();	//输出Child
}
{
	const int value = 10;
	int *value1 = const_cast<int*>(&value);
	//int *value1 = static_cast<int*>(&value);			//无法从“const int *”转换为“int *”
	*value1 = 1;										//value = 1 value1 = 0x0026fe48

	int value2 = reinterpret_cast<int>(value1);			//value2 = 0x0026fe48
	//int value2 = static_cast<int>(value1);			//error C2440: “static_cast”: 无法从“int *”转换为“int”
}

//条款28:避免返回一个handle指向对象的内部成分
//	1.当类定义了一个函数来返回其内部数据的一个指针或者引用的时候,此时会破坏数据的封装性
class CTest
{
public:
	CTest(){pValue = new int(0);}
	~CTest(){delete pValue;}
	int& GetValue() const {return *pValue;}	//即使此函数是const的,也不能改变数据封装性被破话的事实

private:
	int *pValue;
};
CTest Test;
Test.GetValue() = 10;			//此举就是破话了数据的封装性
int value = Test.GetValue();	//value = 10
//	2.当将上述GetValue函数的返回类型也用const修饰,那么就可以避免带来数据封装性的破话,但是,若pValue指向的内存被释放,那么就将带来指针空悬问题。
//	3.有时候必须返回类的成员数据的引用,比如vector中的[]操作。但是使用的时候也必须小心。

//条款30:透彻了解inline的里里外外
//	1.将大多数inline限制在小型的、被频繁调用的函数身上,可以使代码膨胀问题最小化,使程序速度提升最大化。
//	2.inline函数是编译时期的,可能会对inline函数的调试产生问题。
//	3.不能滥用inline,滥用inline可能会导致程序体积过大,也可能导致额外的换页行为,降低指令高速缓冲装置的击中率,以及伴随而来的效率问题。

//条款31:将文件间的编译依存关系降至最低
//	1.若在类A中定义了B类对象,那么类A所在的头文件一般都需要#include "B.h",那么当B类改变后,类A所在的头文件也必须重新编译。
//	2.针对上述情况,若类A定义的是B类的指针对象,则只需要使用前置说明而不需要在类A所在的头文件中#include "B.h",那么就不需要在B类改变后,重新编译类A所在的头文件。
//	3.综上可知,以声明的依存性替代定义的依存性,那正是编译依存性最小化的本质。现实中,让头文件尽量自给自足,万一做不到,则让它与其他文件内的声明式相依。
//	4.综上可知,尽量不要在头文件中#include其他头文件,从而避免产生依赖性编译。尽量在头文件中使用前向声明,而在cpp文件中使用#include
//	5.在头文件中,要以引用或者指针替代对象。
//	6.将类的声明和定义分别置于两个不同的文件,以降低文件间的编译依存关系。

  

时间: 2024-12-29 09:21:05

Effective C++ 5.实现的相关文章

《Effective C++》读书笔记汇总

我之前边读<Effective C++>边写下每个条款的读书笔记,这一版是C++11之前的版本.这里我将每个条款令我印象深刻的点小结一下. 1.C++包括:Plain C(面向过程).OOP(面向对象).模板(泛型和模板元编程).STL(C++标准库). 2.用inline.enum.const代替#define.#define定义的宏,一旦复杂起来,高手都很难掌控.不要带入C的习惯. 3.灵活使用const前缀.不需要进行改变的数据加上const前缀.指针的const前缀有两种形式,cons

Effective Java之内部类

Effective Java中对类的权限,接口等的要求,总结起来就是够用就行,不要赋予过多的访问权限,类的定义也是,如果某个类只会在类的内部使用,那就将该类定义为内部类吧. 内部类分为四种: 1.静态内部类:静态内部类就是在class前面多了static关键词的内部类,这种类和类的静态方法和静态变量一样,针对类本省进行操作,在静态内部类中可以随意访问其所在类的静态方法和静态变量. 2.非静态内部类:和静态内部类相对于,其实在类内部定义的所有东西只是受到访问修饰符的限制,所以非静态内部类和类的非静

学习日记之状态模式和Effective C++

状态模式(State):当一个对象内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类. (1),状态模式主要负责解决的是当控制一个对象转换的条件表达式过于复杂时的情况.把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化. (2),状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来. (3),将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和

Effective Objective-C 2.0重读笔记---1

上次看这本书的时候匆匆走了一遍,最近不太忙,重温了一遍,把笔记写出来~.. 有兴趣的可以去买一本,感觉这本书还是挺不错的 由于大部分是在坐车的时候用手机写的,所以代码很少,图也很少 1. 尽量使用向前声明,延后引入头文件的时间,这样可以减少编译时间2. 使用arraywithobjects:....如果遇到为空的变量,就会自动终止,后面的变量便会添加不上,切不会报错,会造成数据不一致问题,所以尽量使用字面量语法创建相关对象,减少出错且减少代码量3. 使用字面量创建的对象都是不可变的,如果要获得可

Effective前端2:优化html标签

  借用Effective之名,开始写Effective系列,总结一些前端的心得. 有些人写页面会走向一个极端,几乎页面所有的标签都用div,究其原因,用div有很多好处,一个是div没有默认样式,不会有margin.background等初始化设置,另外可能会觉得不用div还能用啥.所以看他的页面,一展开是div,再展开还是div,展开四.五层都是div. 这样对用户来说虽然没什么区别,但是作为一名有追求的程序员,这种写法看起来是比较难受的.有些人虽然知道html5新增了很多标签,但也不怎么去

Effective前端1:能使用html/css解决的问题就不要使用JS

  借用Effective之名,开始写Effective系列,总结一些前端的心得. 为什么说能使用html/css解决的问题就不要使用JS呢?两个字,因为简单.简单就意味着更快的开发速度,更小的维护成本,同时往往具有更好的体验,下面介绍几个实例. 1. 导航高亮 导航高亮是一种很常见的问题,包括当前页面的导航在菜单里面高亮和hover时高亮.你可以用js控制,但是用一点CSS技巧就可以达到这个目的,不需要使用JS. 在正常态时,每个导航的默认样式为: 正常态透明度为0.5 CSS 1 2 3 n

【总结】Effective java经验之谈,类与接口

转载请注明出处:http://blog.csdn.NET/supera_li/article/details/44940563 Effective Java系列 1.Effective java经验之谈,创建和销毁对象 2.Effective java经验之谈,泛型 3.Effective java经验之谈,类与接口 4.Effective java经验之谈,通用方法 5.Effective java经验之谈,枚举,注解,方法,通用设计,异常 6.Effective java经验之谈,并发编程

阅读《effective java-第17条》遇到的问题解决与分享

问题背景 最近这2天准备重新看一遍<effective java>,发现这些经典的书籍真的是看一遍又有一遍的感受.也越来越觉的学习的过程是一个重复的过程.这次遇到的问题是在第17条中看到的,看了蛮久都没有看懂视例代码.第17条的内容是要么为继承而设计,并提供文档说明,要么就禁止继承.在其中有一段示例构造器决不能调用可被覆盖的方法代码如下: 父类代码 package com.sitech.test; /** * effect of java * @author liaowp * */ publi

《Effective C++》之条款34:区分接口继承和实现继承

<Effective C++> 条款34:区分接口继承和实现继承 Public继承由两部分组成 函数接口继承 函数实现继承 三种可能面对的继承 derived class 只继承成员函数的接口 derived class 同时继承函数的接口和实现,但又希望能够覆写它们所继承的实现 derived class 同时继承函数的接口和实现,但不允许覆写任何东西 总结: 接口继承和实现继承不同.在public继承下,derived classes 总是继承base class 的接口. Pure vi

EFFECTIVE JAVA 第十章 并发

EFFECTIVE  JAVA  第十章  并发 66.同步访问共享的可变数据 *java语言规范保证读或写一个变量是原子的(可以保证返回的值是某个线程保存在该变量中的),除非这个变量的类型为long或double.(但并不保证一个线程写入的值对于另一个线程是可见) *synchronized修饰方法.synchronized代码块可以实现同步 *volatile修饰的变量只保证读取的是主存里最新的值而不是内存中该值的拷贝,使用volatile变量必须遵循(即变量真正独立于其他变量和自己以前的值