Effective C++ Item 27 少做转型操作
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
todo Item34
旧式转型
(T) expression 或 T (expression)
新式转型
const_cast<T>(expression)
通常被用来将对象的常量性转除(cast away the constness)
dynamic_cast<T>(expression)
运行“安全向下转型”,也就是用来决定某对象是否归属继承体系中的某个类型。
reinterpret_cast<T>(expression)
运行低级转型 //不太懂??
static_cast<T>(expression)
强迫隐式转换
//旧式转型与新式转型
class Widget{
public:
explicit Widget(int size);
//...
}
void soSomeWork(const Widget &w);
doSomeWork(Widget(15)); //以一个int加上“函数风格”的转型动作创建一个Widget.
doSomeWork(static_cast<Widget>(15)); //以一个int加上“C++风格”的转型动作创建一个Widget
class Base{...};
class Derived: public Base{...};
Derived d;
Base *pb = &d;
有时候上述两个指针值并不同样 。可能会有个偏移量在执行期被施行于Derived *指针上。
对象的布局方式和它们的地址计算方式随编译器的不同而不同。
经验:假设能够,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts。假设有个设计须要转型动作,试着发展
无需转型的替代设计
演示样例1:
class Window{ //base class
public:
virtual void onResize(){...} //base onResize 实现代码
//...
};
class SpecialWindow: public Window{ //derived class
public:
virtual void onResize(){
static_cast<Window>(*this).onResize(); //derived onResize 实现代码。将*this转型为Window,然后调用其 onResize。 错误
//onResize 操作的是转型生成的暂时对象的数据
//... 这里进行 SpecialWindow 专属行为
}
}
纠正
class SpecialWindow: public Window{
public:
virtual void onResize(){
Window::onResize(); //调用Window::onResize作用于*this身上
}
}
演示样例2:之所以须要 dynamic_cast ,一般是由于你想在一个你认定为derived class 对象身上运行 derived class操作函数。但你的手上却仅仅有一个
“指向base”的pointer或reference。你仅仅能靠它们来处理对象。
class Window {...};
class SpecialWindow: public Window{
public:
void blink();
//...
};
typedef std::vector<std::tr1::shared_ptr<Window> > VPW;
VPW winPtrs;
//...
for(VPW::iterator iter = winPtrs.begin(); iter != winPtrs.end(); ++iter){
if(SpecialWindow *psw = dynamic_cast<SpecialWindow*> (iter->get())) //不希望使用 dynamic_cast,由于很多实现版本号运行速度相当慢
psw->blink();
}
纠正1:使用类型安全容器。使用容器并在当中存储直接指向 derived class 对象的指针。消除了“通过 base class 接口处理对象”的须要。
只是这样的做法无法在同一个容器里存储指针“指向全部可能之各种Window派生类”。
假设真要处理多种窗体类型,须要多个容器。
typedef std::vector<std::tr1::shared_ptr<SpecialWindow> >VPSW;
VPSW winPtrs;
//...
for(VPSW::iterator iter = winPtrs.begin(); iter != winPtrs.end(); ++iter){
(*iter)->blink();
}
纠正2:将 virtual 函数往继承体系上方移动。在base class 内提供 virtual 函数做你想对各个 Window 派生类做的事。
class Window{
public:
virtual void blink(){} //缺省实现代码 “什么也没做”。
//<span style="color:#ff0000;">Item 34 --> </span>
//...
};
class SpecialWindow: public Window{
public:
virtual void blink(){...}; //在此class内。blink做某些事
//...
};
typedef std::vector<std::tr1::shared_ptr<Window> > VPW;
VPW winPtrs;
//...
for(VPW::iterator iter = winPtrs.begin(); iter != winPtrs.end(); ++iter){
psw->blink();
}
Effective C++ Item 27 少做转型操作的更多相关文章
- [Effective C++ --027]尽量少做转型动作
引言 ...
- 读书笔记_Effective_C++_条款二十七:尽量少做转型动作
有关转型的几种做法,已经在早些的博客中写过了.这里先简单回顾一下,再讲一讲effective中对之更深入的阐述. 转型可以按风格可以分成C风格转型和C++风格转型两大类,C风格转型很容易看到,因为我们 ...
- 读书笔记 effective c++ Item 27 尽量少使用转型(casting)
C++设计的规则是用来保证使类型相关的错误不再可能出现.理论上来说,如果你的程序能够很干净的通过编译,它就不会尝试在任何对象上执行任何不安全或无意义的操作.这个保证很有价值,不要轻易放弃它. 不幸的是 ...
- Effective C++ -----条款27:尽量少做转型动作
如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts.如果有个设计需要转型动作,试着发展无需转型的替代设计. 如果转型是必要的,试着将它隐藏于某个函数背后.客户随后可以调用该 ...
- 条款27:尽量少做转型动作(Minimize casting)
NOTE : 1.如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts. 如果有个设计需要转型动作,试着发展无需转型的替代设计. 2.如果转型是必须要的,试着将它隐藏于某个函 ...
- [EffectiveC++]item27:尽量少做转型动作
- Effective C++:条款27——条款
条款27:尽量少做转型动作 单一对象可能拥有一个以上的地址!
- Effective C++ 条款27
尽量少做转型动作 尽量少做转型动作有什么目的?非常明显无非就是提高程序的稳定性.提高程序的运行效率. 那么.有哪些转型方式?每种方式都有什么弱点? 这是我们本节学习的重点. C++有四种转型: con ...
- Effective C++:规定27:尽量少做动作的过渡
(一个)C风格遗留转换: (T)expression T(expression) (二)C++提供四种新式转型: (1)const_cast<T>(expression):去除表达式的常量 ...
随机推荐
- 【原创翻译】链接DLL至可执行文件---翻译自MSDN
可执行文件.exe链接(或加载)DLL有以下两种形式: 隐式链接 显式链接 隐式链接是指静态加载或在程序加载时动态链接. 通过隐式链接,在使用DLL时,可执行文件链接到一个由生成DLL的人提供的导入函 ...
- No-8.其他命令
其他命令 目标 查找文件 find 软链接 ln 打包和压缩 tar 软件安装 apt-get 01. 查找文件 find 命令功能非常强大,通常用来在 特定的目录下 搜索 符合条件的文件 序号 命令 ...
- avalon转成Vue
需求: 旧项目中有部分页面是用avalon写的,avalon存在页面刷新,会出现重复行的问题,数组渲染出现重复行bug, 需要转成vue 总结 记录了一下大概需要改的地方 1. avalon中的ms- ...
- mysql alter修改数据库表结构用法
1.alter操作表字段 (1)增加字段 alter table 表名 add 字段名 字段类型: alter table student add name varchar(10): (2)修改字段 ...
- 201621123079《java程序设计》第六周作业总结
作业06-接口.内部类 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 2. 书面作业 1. c ...
- logging日志模块配置
logging日志模块 日志级别 日志一共分成5个等级,从低到高分别是: 1)DEBUG 2)INFO 3)WARNING 4)ERROR 5)CRITICAL 说明: DEBUG:详细的信息,通常只 ...
- noi.ac NOIP2018 全国热身赛 第四场 T1 tree
[题解] 考虑从小到大枚举边权,按顺序加边. 当前树被分成了若干个联通块,若各个块内的点只能跟块外的点匹配,那么最终的min g(i,pi)一定大于等于当前枚举的边. 判断各个联通块内的点是否全部能跟 ...
- MySQL之federated
由于夸服务器查询的限制,federated能够使得所有的表像是在同一台服务器上查询 (show engines-->no-->在my.ini里面添加fedrated) 经过测试,在开启fe ...
- Charm Bracelet(01背包)
Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fil ...
- Tao Tao要吃鸡(01背包)
题目描述 Taotao的电脑带不动绝地求生,所以taotao只能去玩pc版的荒野行动了,和绝地求生一样,游戏人物本身可以携带一定重量m的物品,装备背包之后可以多携带h(h为0代表没有装备背包)重量的东 ...