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 这本大山,但是读到一半就放弃了.过长的篇幅,让 ...
随机推荐
- Oracle 数据库安装
下载 www.oracle.com ->Downloads -> Oracle Database 安装: 解压到同一文件夹下 仅安装数据库软件 单实例数据库安装 企业版 oracle基目录 ...
- 利用Excel画柱状图,并且包含最大最小值
如何利用Excel画出如上样式的图? 1.绘制柱状图.如何绘制柱状图,操作非常简单,选中数据,点击合适的图表样式即可. 2.添加误差线.选中已绘制好的图,添加误差线.如果误差线没有出现,可以使用”更多 ...
- 【转】Xamarin.Android 入门之:Xamarin+vs2015 环境搭建
Xamarin.Android 入门之:Xamarin+vs2015 环境搭建 一.前言 此篇博客主要写了如何使用搭建xamarin开发的环境,防止我自己万一哪天电脑重装系统了,可以直接看这篇博客 ...
- JS框架比较
https://www.oschina.net/translate/comparison-of-js-frameworks这几个框架我都用过1. Ember 2.x已经没有script标签在页面里了, ...
- Ubuntu 设置Vim tab为四个空格
使用root权限打开 /etc/vim/vimrc 添加下列配置 set tabstop= set softtabstop= set shiftwidth= set noexpandtab set n ...
- php--数据库三范式
关系数据库的几种设计范式介绍1.第一范式(1NF) 在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库. 所谓第一范式(1NF)是指数据 ...
- jQuery 复选框全选反选
<script type="text/javascript"> $(function(){ //全选 $("#CheckedAll").click( ...
- centos 安装 openerp
遇到问题:近日公司提出openerp的搭建,觉得openerp里的有些模块比较适合公司,openerp的运作,估计会有利于公司系统化的管理.于是我就去了解openrp,然后来搭建这套强大的系统. 解决 ...
- jQuery实现隔行变色
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- ZOOKEEPER解惑
现在网上关于ZooKeeper的文章很多,有介绍Leader选举算法的,有介绍ZooKeeper Server内部原理的,还有介绍ZooKeeper Client的.本文不打算再写类似的内容,而专注与 ...