本文为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 少做转型操作的更多相关文章

  1. [Effective C++ --027]尽量少做转型动作

    引言                                                                                                   ...

  2. 读书笔记_Effective_C++_条款二十七:尽量少做转型动作

    有关转型的几种做法,已经在早些的博客中写过了.这里先简单回顾一下,再讲一讲effective中对之更深入的阐述. 转型可以按风格可以分成C风格转型和C++风格转型两大类,C风格转型很容易看到,因为我们 ...

  3. 读书笔记 effective c++ Item 27 尽量少使用转型(casting)

    C++设计的规则是用来保证使类型相关的错误不再可能出现.理论上来说,如果你的程序能够很干净的通过编译,它就不会尝试在任何对象上执行任何不安全或无意义的操作.这个保证很有价值,不要轻易放弃它. 不幸的是 ...

  4. Effective C++ -----条款27:尽量少做转型动作

    如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts.如果有个设计需要转型动作,试着发展无需转型的替代设计. 如果转型是必要的,试着将它隐藏于某个函数背后.客户随后可以调用该 ...

  5. 条款27:尽量少做转型动作(Minimize casting)

    NOTE : 1.如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts. 如果有个设计需要转型动作,试着发展无需转型的替代设计. 2.如果转型是必须要的,试着将它隐藏于某个函 ...

  6. [EffectiveC++]item27:尽量少做转型动作

  7. Effective C++:条款27——条款

    条款27:尽量少做转型动作 单一对象可能拥有一个以上的地址!

  8. Effective C++ 条款27

    尽量少做转型动作 尽量少做转型动作有什么目的?非常明显无非就是提高程序的稳定性.提高程序的运行效率. 那么.有哪些转型方式?每种方式都有什么弱点? 这是我们本节学习的重点. C++有四种转型: con ...

  9. Effective C++:规定27:尽量少做动作的过渡

    (一个)C风格遗留转换: (T)expression T(expression) (二)C++提供四种新式转型: (1)const_cast<T>(expression):去除表达式的常量 ...

随机推荐

  1. ORA-03113: end-of-file on & ORA-07445

    --------------ORA-03113: end-of-file on-------------- SQL> show parameter background_dump; NAME T ...

  2. mysql查询速度慢的原因[整理版]

    在以前的博客中陆续记录了有关查询效率方面的文章.今天在整理一下,写上自己的一些心得记录如下:常见查询慢的原因常见的话会有如下几种:1.没有索引或没有用到索引.PS:索引用来快速地寻找那些具有特定值的记 ...

  3. [LUOGU] P4290 [BZOJ] 1055 [HAOI2008]玩具取名

    题目描述 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用"WING"中任意两个字母代 ...

  4. KVM中存储的配置

    存储配置和启动顺序 QEMU提供了对多种块存储设备的模拟,包括IDE设备.SCSI设备.软盘.U盘.virtio磁盘等,而且对设备的启动顺序提供了灵活的配置. 1. 存储的基本配置选项 在qemu-k ...

  5. qt 窗体间通信

    利用qt的信号和槽,可以完成窗体间的通信,下面列出父子窗口利用信号和槽的相关代码. parent窗口: //parent.h #ifndef PARENT_H #define PARENT_H #in ...

  6. 使用 ES (elasticsearch) 搜索中文

    1.创建索引 curl -XPUT http://172.16.125.139:9200/ques2.创建索引类型 curl -XPOST http://172.16.125.139:9200/que ...

  7. BZOJ 2734 洛谷 3226 [HNOI2012]集合选数【状压DP】【思维题】

    [题解] 思维题,看了别人的博客才会写. 写出这样的矩阵: 1,3,9,... 2,6,18,... 4,12.36,... 8,24,72,... 我们要做的就是从矩阵中选出一些数字,但是不能选相邻 ...

  8. 【HIHOCODER 1049】 后序遍历

    描述 在参与过了美食节之后,小Hi和小Ho在别的地方又玩耍了一阵子,在这个过程中,小Ho得到了一个非常有意思的玩具--一棵由小球和木棍连接起来的二叉树! 小Ho对这棵二叉树爱不释手,于是给它的每一个节 ...

  9. 2017acm南宁现场赛 J题 Rearrangement

    题意: 给定一个2 * n的矩阵, 和 2 * n 个数, 问能不能通过重排列, 使得任意相邻两数不能被3整除 分析: 这题一直卡到最后, 赛后经对面大佬提醒后, 发现统计所有数模三的结果(0,1,2 ...

  10. 【C#】【数据结构】005-栈:顺序栈

    C#数据结构:顺序栈 1.自定义顺序栈结构: /// <summary> /// 顺序栈 /// </summary> /// <typeparam name=" ...