本文为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();
}

最新文章

  1. 脑成像数据分析:Python工具包
  2. c#实现数据的左补右补功能
  3. bnuoj 33648 Neurotic Network(树形模拟题)
  4. AIR 程序开发系列 之五 保存数据的几种方式
  5. PHP数据类型转换(字符转数字,数字转字符)
  6. chromium blog
  7. 【CSS3】边框
  8. Git 子模块 - submodule(转)
  9. K-wolf Number (数位DP)
  10. 初窥async,await
  11. JS 判断是否是手机端并跳转操作
  12. Jordan 块的几何
  13. word如何替换行首?
  14. Java编程的逻辑 (50) - 剖析EnumMap
  15. UIKit&#160;框架之UIAlertController
  16. 自定义提醒视图Alert-动态绘制
  17. JavaScript toString、String和stringify方法区别
  18. Oracle应用技术精华教程:管理还原段
  19. CUDA,cudnn一些常见版本问题
  20. [android] 练习viewpagerindicator的使用(二)

热门文章

  1. QT5:总结篇 控件集合
  2. 第1节 flume:9、flume的多个agent串联(级联)
  3. nginx代理yum
  4. SANBA服务和FTP服务
  5. SONP 是什么
  6. Python数据分析 Pandas模块 基础数据结构与简介(一)
  7. Python中的函数(5)
  8. Android开发——查询/杀死手机里正在运行的进程
  9. UI进阶 即时通讯之XMPP环境搭建
  10. Vmware改成bridge方式联网