C++强制转换之static_cast
来源:互联网 发布:电子网络 编辑:程序博客网 时间:2024/06/04 19:47
static_cast
用法:static_cast<type-id>(expression)
简介:该运算符把expression转换为type_id类型,但没有运行时类型检查来保证转换的安全性。
主要有以下几种用法:
1. 用于类层次结构中基类和派生类之间指针或引用的转换:进行上行转换是安全的,进行下行转换时是不安全的
2. 用于基本数据类型之间的转换
3. 把空指针转换成目标类型的空指针
4. 把任何类型的表达斯转化成void型
下面给出一些具体的示例
例子1
#include <stdio.h>#include <string>using namespace std;class A{public:A(int i) : m_a(i){}void Print(){}private:int m_a;};class B : public A{public:B() : A(1){}virtual ~B() {}virtual void Test() { printf("Test\n"); }};int main(int argc, char** argv){B b;A a = static_cast<A>(b);a.Print();getchar();return 0;}运行结果如下:
m_a: 1
分析:B继承自A,B类型可以上行转换为A类型
例子2
A a = A(1);B b = static_cast<B>(a); //错误,error C2440: “static_cast”: 无法从“A”转换为“B”,无构造函数可以接受源类型,或构造函数重载决策不明确
分析:B虽然继承自A,但A不能强转为B
例子3
#include <stdio.h>#include <string>using namespace std;class A{public:A(int i) : m_a(i){}void Print(){printf("m_a: %d\n", *((int*)this));}A(const A& a){this->m_a = a.m_a;}~A() {}private:int m_a;};class B : public A{public:B() : A(1){}virtual ~B() {}virtual void Test() { printf("Test\n"); }};int main(int argc, char** argv){B* pb = new B();A* pa = static_cast<A*>(pb);pa->Print();getchar();return 0;}
结果如下:
m_a: 1
分析:理所当然,指针的上行转换不会出错
例子4
#include <stdio.h>#include <string>using namespace std;class A{public:A(int i) : m_a(i){}void Print(){printf("m_a: %d\n", *((int*)this));}A(const A& a){this->m_a = a.m_a;}~A() {}private:int m_a;};class B : public A{public:B() : A(1){}virtual ~B() {}virtual void Test() { printf("Test\n"); }};int main(int argc, char** argv){A* pa = new A(1);B* pb = static_cast<B*>(pa);pb->Test();getchar();return 0;}结果:可以运行,但是运行执行到Test时会崩溃
分析:本例中指针pb会有一个vptr,但指向的位置并不是类B的虚表(pb中的vptr并不指向任何虚表,如果A中有虚函数的话,vptr会指向A的虚表),找不到对应虚函数,所以自然会崩溃
例子5
#include <stdio.h>#include <string>using namespace std;class A{public:A(int i) : m_a(i){}void Print(){printf("m_a: %d\n", *((int*)this));}A(const A& a){this->m_a = a.m_a;}~A() {}private:int m_a;};class B : public A{public:B() : A(1){}virtual ~B() {}virtual void Test() { printf("Test\n"); }};int main(int argc, char** argv){B* pb = new B;A* pa = static_cast<A*>(pb);printf("pa: %p, pb: %p\n", pa, pb);pb = static_cast<B*>(pa);printf("pa: %p, pb: %p\n", pa, pb);pb->Test();getchar();return 0;}运行结果如下:
pa: 0051B434, pb: 0051B430pa: 0051B434, pb: 0051B430Test
分析:转化不会出错,具体原因跟类的对象的内存模型有关,这里不做解释,另外,如果在类A中加个随便加个虚函数,pa和pb将会相同,另外,无论怎么转换,vptr永远指向类B的虚表。
例子6
class C{};class D: public C{};int main(int argc, char** argv){D* d = new C();C* c = static_cast<C*>(d);getchar();return 0;}
结果,编译通过运行成功
class C{};class D: protected C{};int main(int argc, char** argv){D* d = new D();C* c = static_cast<C*>(d);getchar();return 0;}
结果,编译出错,error C2243: “static_cast”: 从“D *”到“C *”的转换存在,但无法访问
class C{};class D: private C{};int main(int argc, char** argv){D* d = new D();C* c = static_cast<C*>(d);getchar();return 0;}结果,编译出错,error C2243: “static_cast”: 从“D *”到“C *”的转换存在,但无法访问
如果有两个类A和B,两者不存在继承关系,它们之间无法通过static_cast进行转换,代码就不上了
例子7
#include <stdio.h>#include <string>using namespace std;class A{public:A(int i) : m_a(i){}~A(){printf("A destruction\n");}private:int m_a;};int main(int argc, char** argv){A* a = new A(1);void* v = static_cast<void*>(a);a = static_cast<A*>(v);int* p = static_cast<int*>(v);delete a;getchar();return 0;}
编译通过运行成功,static_cast可以将void*型转换为任意类型,dynamic_cast则不行,void*类型不能作为括号中的参数
0 0
- C++强制转换之static_cast
- C++强制类型转换之static_cast
- C++ 之强制类型转换 static_cast
- static_cast与c风格的强制类型转换
- 【C++】强制类型转换(static_cast,reinterpret_cast,const_cast,dynamic_cast,explicit)
- static_cast,reinterpret_cast及C的强制类型转换
- static_cast与c风格的强制类型转换比较
- [C++] 强制类型转换static_cast、dynamic_cast、reinterpret_cast和const_cast
- c++dynamic_cast、const_cast 、static_cast、reinterpret_cast强制类型转换
- 强制转换函数(const_cast,reinterpret_cast,static_cast,dynamic_cast)
- c++强制类型转换:dynamic_cast、const_cast 、static_cast
- 强制转换函数(const_cast,reinterpret_cast,static_cast,dynamic_cast)
- C++ 强制类型转换 static_cast<new_type>(expression)
- c++中的强制转换static_cast、dynamic_cast、reinterpret_cast
- C++强制类型转换操作符 static_cast
- C++强制类型转换操作符 static_cast
- static_cast与强制类型转换的区别
- c语言之强制类型转换
- Swift中文教程(五)控制流
- Ubuntu14.04 emacs配置cscope
- [HDU1269]迷宫城堡(Tarjan求强连通分量)
- LintCode_1_A + B 问题
- leetcode 46,47. Permutations I/II 全排列问题 java
- C++强制转换之static_cast
- CUDA内核函数的连续执行
- Ternary Calculation(也不用栈,注意输入方式即可,直接解决)
- 【SSH进阶之路】Struts + Spring + Hibernate 进阶开端(一)
- 实习过程中linux相关开发学习总结(一)
- 内存池——第一章 几种常用的内存池技术
- git clone远程库错误
- Android使用ListView时item失效解决方案
- 新编日语第四册(修订版)第03课 应用文