旧式的类型转换中有俩种(Effect C++)
//C风格 (T)expression
(int)a//比如这样子 //函数风格 T(expression)
doSomeWork(Widget(15)) 这里15作为一个参数给类Widget,会以转型动作创建一个Widget
而C++提供了四种新式转换。
(1)const_cast:通常用来把对象的常量性一处掉,是唯一有此能力的C++ style转型操作符。
(2)dynamic_cast:用来指向安全向下转型
是这样的,比如有一个base类,有很多派生类,在这个继承体系里,可以用来决定对象是否归属于继承体系中的某个类型(向下的,也就是从基类指针转变到某个派生类指针)
这是唯一一个无法通过旧式语法执行的动作,是唯一可能耗费重大运行成本的转型动作。
成本非常高昂。
(3)static_cast:用来强迫隐式转换。
比如把non-const对象转换为const对象(反过来不行,只有const_cast能做到),或者把int转为double等,还可以把void*指针转为typed指针,把pointer-to-base转为pointer-to-derived。
(4)reinterpret_cast:意图执行低级转型,效果取决于编译器。
这个类型转换会重新去解释内存中存放的数据的类型,比如说我们强行把一个指向int型的指针(在内存中就是一个整数,只不过是用来解释为地址的),去解释为一个int,它可以满足各种类型的转换,但是对结果不做保证。
转型实际上是会产生一些代码的,比如说int和double在内存里表示形式不同,如果我们把int数转型为double,那在内存中存储的数据肯定是会改变的,是做了改变的。
//还有一个有趣的事情,
//基类 class Window{ public: virtual void onRize(){...} ... } //派生类 class SpecialWindow:public Window{ public: virtual void onResize() { //转型,试图调用Window的onRize(); //这是行不通的! static_cast<Window>(*this).onResize(); } ...//secialWindows专属行为 }
这一段程序希望吧*this转型为Window,然后调用Window::onResize。但是实际上,它调用的并不是当前对象上的函数,而是稍早转型动作所建立的一个"*this对象之base class成分”的暂时副本身上的onResize
函数就是函数,成员函数只有一份,“调用哪个对象身上的函数”有什么关系呢,关键在于成员函数身上都有一个(非静态的)*this指针,会影响到成员函数操作的数据。
所以实际上!他不是在当前对象身上,调用Window::onResize之后,再执行SecialWindow专属动作,他调用的是哪个临时副本,。如果Window::onResize修改了对象的内容,当前的对象其实没有改动,改动的是副本。而SecialWindow::如果改动对象,就真的会改动。
为了避免这种情况,最好这样写
virtual void onResize() { Window::onResize();//调用Window::onResize作用于*this的指针上 }
//-----之后也许需要补充一些dynamic_cast相关的问题。参见cherno的dynamic_cast相关视频