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:
CChild() : nValue(-1){} public:
virtual void Fun(){printf("Child\n");} void FunTest()
{
char buff[10] = {};
sprintf_s(buff, "%d\n", nValue);
printf(buff);
} public:
int nValue;
}; int main()
{
{
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
}
{
CFather Father;
CChild *pChild = static_cast<CChild*>(&Father); //pChild = 0x0036fd04
pChild->Fun(); //输出Father
pChild->FunTest(); //运行奔溃
} {
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.将类的声明和定义分别置于两个不同的文件,以降低文件间的编译依存关系。
Effective C++ 5.实现的更多相关文章
- Effective前端2:优化html标签
div { float: left; } .keyboard > div + div { margin-left: 8px; } --> div{display:table-cell;ve ...
- Effective java笔记(二),所有对象的通用方法
Object类的所有非final方法(equals.hashCode.toString.clone.finalize)都要遵守通用约定(general contract),否则其它依赖于这些约定的类( ...
- 《Effective java》-----读书笔记
2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己!预计在2016年要看12本书,主要涉及java基础.Spring研究.java并 ...
- 《Effective Java》学习笔记——积累和激励
从一个实际案例说起 国庆长假前一个礼拜,老大给我分配了这么一个bug,就是打印出来的报表数量为整数的,有的带小数位,有的不带,毫无规律. 根据短短的两个多月的工作经验以及猜测,最终把范围缩小到以下这段 ...
- Effective前端5:减少前端代码耦合
什么是代码耦合?代码耦合的表现是改了一点毛发而牵动了全身,或者是想要改点东西,需要在一堆代码里面找半天.由于前端需要组织js/css/html,耦合的问题可能会更加明显,下面按照耦合的情况分别说明: ...
- Effective前端4:尽可能地使用伪元素
伪元素是一个好东西,但是很多人都没怎么用,因为他们觉得伪元素太诡异了.其实使用伪元素有很多好处,最大的好处是它可以简化页面的html标签,同时用起来也很方便,善于使用伪元素可以让你的页面更加地简洁优雅 ...
- Effective前端3:用CSS画一个三角形
p { text-indent: 2em } .triangle-container p { text-indent: 0 } img { margin: 15px 0 } 三角形的场景很常见,打开一 ...
- Effective前端1:能使用html/css解决的问题就不要使用JS
div{display:table-cell;vertical-align:middle}#crayon-theme-info .content *{float:left}#crayon-theme- ...
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- effective java 读后感
think in java , effective java 这两本书一直都在java的生态圈中经久不衰.本来想着先翻过 think in java 这本大山,但是读到一半就放弃了.过长的篇幅,让 ...
随机推荐
- java,for循环中的穷举、迭代、冒泡例题
1.100以内与7相关的数 //100以内与7相关的数: public static void main1(String[] args) { for(int i=1;i<=100;i++){ i ...
- [Oracle][ODBC SQL Server Driver][SQL Server]对象名 'RECOVER.HS_TRANSACTION_LOG' 无效(转)
原帖由 qingyun 于 2010-6-21 15:44 发表 在写pl/sql的时候,有个很重要的注意点:比如:begin update 某个sqlserver的表@dblink名字 .... ...
- html5之canvas初解
<canvas> 元素本身并没有绘制能力(它仅仅是图形的容器) - 必须使用脚本来完成实际的绘图任务. getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属 ...
- [收藏]NET技术+25台服务器怎样支撑世界第54大网站
.NET技术+25台服务器怎样支撑世界第54大网站 英文原文:StackOverflow Update: 560M Pageviews A Month, 25 Servers, And It's ...
- JS 去字符串空格 总结
str为要去除空格的字符串: 去除所有空格: str = str.replace(/\s+/g,""); 去除两头空格: str = str.replace(/^\s+|\s+$/ ...
- sp.net2.0中的新增控件BulletedList的一些高级用法
asp.net2.0新增了一个BulletedList控件,通过它可以以列表形式显示数据,而不必再用Repeater,Datalist等实现相同的效果.今天做程序的时候正好用到了这个控件,就把它的一些 ...
- linux configure
Linux环境下的软件安装,并不是一件容易的事情;如果通过源代码编译后在安装,当然事情就更为复杂一些;现在安装各种软件的教程都非常普遍;但万变不离其中,对基础知识的扎实掌握,安装各种软件的问题就迎刃而 ...
- yaf性能测试(wamp环境)
1实现mvc 出现helloword,成功 2.controller重定向 $get = $this->getRequest()->getQuery("get", &q ...
- net use
net use * \\ipaddr\share "password" /user:"username" /persistent:yes 在运行中输入“\\”+ ...
- Python 时间 日期常见操作
import datetime,time dtstr = '2014-02-14 21:32:12' a = datetime.datetime.strptime(dtstr, "%Y-%m ...