staitic_cast原理与使用
2013-07-29 10:55 Dirichlet 阅读(1847) 评论(0) 编辑 收藏 举报本文以下述结构为例:
总结如下:
1) static_cast用于有直接或间接关系的指针或引用之间 转换。没有继承关系的指针不能用此转换,即使二者位于同一类体系中。比如,Left,Right之间不能用static_cast,编译器无法确定二指针如何移动偏移量,请考虑Left,Right还有可能位于其他类体系中。
如果Left,Right指向同一子对象,可以用安全的dynamic_cast。
2) 向上类型转换总是成功的,static_cast关键字可写可不写,也就是分别对应显示或隐式的static_cast。也可以用括号形式的C语言风格来写,pRight = (Right*)pBottom;
3) static_cast也可用于向下类型转换,但是开发人员负责向下转换的成功与否,也就是必须确定父类指针指向的是期望的子类对象,转换才是有意义的。有时static_cast用于向下类型转换会出现编译错误,比如对于典型的虚继承的菱形结构,Left, Right都虚继承自Top,Left* left = static_cast<Left*>(top1); 会有编译错误,因为Left,Right可能同时位于多个不同的类层次结构中,编译器无法静态分析出指针的偏移量,Top也没有额外的指针去获取这个偏移量。总结一下就是向下类型类型转换最好不要用static_cast,换成dynamic_cast试试。
4) static_cast效率比dynamic_cast高,请尽可能用。大部分情况下static_cast编译时就可以确定指针移动多少偏移量,但是对于虚继承要用到虚指针确定一个到虚基类的偏移量,稍微麻烦一些。
#include <iostream> using namespace std; class Left { public: Left():x(1){} private: int x; }; class Right { public: Right():y(2){} private: int y; }; class Bottom: public Left, public Right { public: Bottom():z(3){} private: int z; }; int main() { // implicit static_cast Bottom* pBottom = new Bottom(); Right* pRight = pBottom; Left* pLeft = pBottom; cout<<"Bottom Address: "<<(int)(pBottom)<<endl; cout<<"Right Address: "<<(int)(pRight)<<endl; cout<<"Left Address: "<<(int)(pLeft)<<endl<<endl; // explicit static_cast pRight = static_cast<Right*>(pBottom); pLeft = static_cast<Left*>(pBottom); cout<<"Bottom Address: "<<(int)(pBottom)<<endl; cout<<"Right Address: "<<(int)(pRight)<<endl; cout<<"Left Address: "<<(int)(pLeft)<<endl<<endl; // another style pRight = (Right*)pBottom; pLeft = (Left*)pBottom; cout<<"Bottom Address: "<<(int)(pBottom)<<endl; cout<<"Right Address: "<<(int)(pRight)<<endl; cout<<"Left Address: "<<(int)(pLeft)<<endl<<endl; // down cast, dev is responsible for the casting pRight = static_cast<Right*>(pBottom); pLeft = static_cast<Left*>(pBottom); Bottom* pBottom1 = static_cast<Bottom*>(pRight); Bottom* pBottom2 = static_cast<Bottom*>(pLeft); cout<<"Bottom Address: "<<(int)(pBottom1)<<endl; cout<<"Bottom Address: "<<(int)(pBottom2)<<endl<<endl; pBottom1 = (Bottom*)(pRight); //啥意思?需要再仔细实验。
pBottom2 = (Bottom*)(pLeft); cout<<"Bottom Address: "<<(int)(pBottom1)<<endl; cout<<"Bottom Address: "<<(int)(pBottom2)<<endl<<endl; // // pLeft = static_cast<Left*>(pRight); // can't pass compiling, use the method below. pLeft = static_cast<Left*>(static_cast<Bottom*>(pRight)); }