徐州网站推广,百度推广查询,免费的平面设计网站,科技部网站建设合同范本理解C强制类型转换 文章目录 理解C强制类型转换理解C强制转换运算符1 static_cast1.1. static_cast用于内置数据类型之间的转换1.2 用于指针之间的转换 1.3 用于基类与派生类之间的转换2. const_cast2.1示例12.2 示例2——this指针 3.reinterpret_cast4.dynamic_cast C认为C风格…理解C强制类型转换 文章目录 理解C强制类型转换理解C强制转换运算符1 static_cast1.1. static_cast用于内置数据类型之间的转换1.2 用于指针之间的转换 1.3 用于基类与派生类之间的转换2. const_cast2.1示例12.2 示例2——this指针 3.reinterpret_cast4.dynamic_cast C认为C风格的类型转换过于松散可能会带来隐患不够安全。C推出了新的类型转换来替代C风格的类型转换采用更严格的语法检查降低使用风险。C新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast用于支持C风格的类型转换。C的类型转换只是语法上的解释本质上与C风格的类型转换没什么不同C语言做不到事情的C也做不到。 
C语言强制类型转换是有一定风险的有的转换并不一定安全如 
把整型数值转换成指针把基类指针转换成派生类指针把一种函数指针转换成另一种函数指针把常量指针转换成非常量指针等。 
总结C语言强制类型转换缺点主要是为了克服C语言强制类型转换的以下三个缺点。 
没有从形式上体现转换功能和风险的不同。将多态基类指针转换成派生类指针时不检查安全性即无法判断转换后的指针是否确实指向一个派生类对象。难以在程序中寻找到底什么地方进行了强制类型转换强制类型转换是引发程序运行时错误的一个原因因此在程序出错时可能就会想到是不是有哪些强制类型转换出了问题。 例如将int 强制转换成 double是没有风险的而将常量指针转换成非常量指针将基类指针转换成派生类指针都是高风险的而且后两者带来的风险不同(即可能引发不同种类的错误)C语言的强制类型转换形式对这些不同并不加以区分 举例1. 把整型数值转换成指针编译阶段不报错运行阶段报错  
理解C强制转换运算符 
C 引入了四种功能不同的强制类型转换运算符以进行强制类型转换 
static castconst castreinterpret_castdynamic_cast 
语法(目标类型)表达式或目标类型(表达式); 
static_cast目标类型(表达式);const_cast目标类型(表达式);reinterpret_cast目标类型(表达式);dynamic_cast目标类型(表达式); 1 static_cast 
1.1. static_cast用于内置数据类型之间的转换 
用途基本等价于隐式转换的一种类型转换运算符可使用于需要明确隐式转换的地方。 
可以用于低风险的转换 
整型和浮点型字符与整形转换运算符*空指针转换为任何目标类型的指针 
不可以用与风险较高的转换 
不同类型的指针之间互相转换整型和指针之间的互相转换不同类型的引用之间的转换 
#include iostream
using namespace std;
class CInt
{
public:operator int(){this-m_Int  128;return m_Int;}
int m_Int;};
int main(int argc, char* argv[])
{int i  3;float f  10.0f;f  i;                          //可以隐式转换会出现警告int”转换到“float”可能丢失数据	long m  i;                     // 绝对安全可以隐式转换不会出现警告。double dd  1.23;long m1  dd;                        // 可以隐式转换会出现可能丢失数据的警告。long m2  (long)dd;                 //  C风格显式转换不会出现警告。long m3  static_castlong(dd);    //  C风格显式转换不会出现警告。cout  m1  m1  ,m2  m2  ,m3  m3  endl;//低风险的转换整型与浮点型字符型与整型void *指针转换为任意类型指针//字符型与整型char cha;int n  5;n  static_castint(ch);//void *指针转换为任意类型指针void *p  nullptr;int *p1  static_castint *(p);//转换运算符,类与其他类型CInt Obj;//int kObj ;//可以隐式转换int k  static_castint(Obj);cout  k  k  endl;}1.2 用于指针之间的转换 
C风格可以把不同类型的指针进行转换。 C不可以需要借助void *。 
#include iostream
using namespace std;
class CInt
{
public:operator int(){this-m_Int  128;return m_Int;}
int m_Int;};
int main(int argc, char* argv[])
{int i  3;float f  10.0f;f  i;                          //可以隐式转换会出现警告int”转换到“float”可能丢失数据	long m  i;                     // 绝对安全可以隐式转换不会出现警告。double dd  1.23;long m1  dd;                        // 可以隐式转换会出现可能丢失数据的警告。long m2  (long)dd;                 //  C风格显式转换不会出现警告。long m3  static_castlong(dd);    //  C风格显式转换不会出现警告。cout  m1  m1  ,m2  m2  ,m3  m3  endl;//低风险的转换整型与浮点型字符型与整型void *指针转换为任意类型指针//高风险的转换整型与指针类型转换//字符型与整型char cha;int n  5;n  static_castint(ch);//void *指针转换为任意类型指针void *p  nullptr;int *p1  static_castint *(p);//转换运算符,类与其他类型CInt Obj;//int kObj ;//可以隐式转换int k  static_castint(Obj);cout  k  k  endl;//}1.3 用于基类与派生类之间的转换 
int main() 
{CFather* pFather  nullptr;CSon* pSon  nullptr;//父类转子类(不安全)//pSon  pFather;pSon  static_castcson*(pFather); //不安全没有提供运行时的检测编译会通过//子类转父类(安全)pFather  pSon;pFather  static castCFather*(pSon);} 2. const_cast 
static_cast不能丢掉指针引用的const和volitale属性const_cast可以。仅用于进行去除 const 属性的转换它也是四个强制类型转换运算符中唯一能够去除 const 属性的运算符。const_cast 只针对指针引用this指针 
2.1示例1 示例1改为 
#include iostream
#include string
int main()
{const int n  5;const std::string s  Inception;//const_cast  只针对指针引用this指针int *k  const_castint*(n);//const_castint*指针类型  n取出变量地址*k  123456;std::cout 改变后的值   *k  std::endl;}#include iostream
#include string
int main()
{const int n  5;const std::string s  Inception;//const_cast  只针对指针引用this指针int *k  const_castint*(n);//const_castint*指针类型  n取出变量地址int k1  const_castint(n);//const_castint引用类型 *k  123456;k1  10000;std::cout 改变后的值   *k  std::endl;std::cout  改变后的值    k1  std::endl;
}2.2 示例2——this指针 
常成员函数——不能修改成员变量的值,使用const_cast让常成员函数可以修改成员变量的值,这个做法感觉有点无聊 
#include iostream
#include string
class CTest
{
public:int m_test100;void foo(int test) const{//m_test  test;//void *p  this;const_castCTest* const(this)-m_test  test;//const_castconst CTest* const(this)-m_test  test;//报错}
};int main()
{int n  5;int* const pn;//p  0x123;CTest t;t.foo(1);std::cout  t.m_test  std::endl;//const int n  5;//const std::string s  Inception;const_cast  只针对指针引用this指针//int *k  const_castint*(n);//const_castint*指针类型  n取出变量地址//int k1  const_castint(n);//const_castint引用类型 //*k  123456;//k1  10000;//std::cout 改变后的值   *k  std::endl;//std::cout  改变后的值    k1  std::endl;
}3.reinterpret_cast 
static_cast不能用于转换不同类型的指针引用不考虑有继承关系的情况reinterpret_cast可以。 reinterpret_cast的意思是重新解释能够将一种对象类型转换为另一种不管它们是否有关系。 语法reinterpret_cast目标类型(表达式); 目标类型和(表达式)中必须有一个是指针引用类型。 reinterpret_cast不能丢掉(表达式)的const或volitale属性。 应用场景 1reinterpret_cast的第一种用途是改变指针引用的类型。 2reinterpret_cast的第二种用途是将指针引用转换成整型变量。整型与指针占用的字节数必须一致否则会出现警告转换可能损失精度。 3reinterpret_cast的第三种用途是将一个整型变量转换成指针引用。 示例 
#include iostream
using namespace std;void func(void* ptr) {  long long ii  reinterpret_castlong long(ptr);cout  ii  ii  endl;
}int main(int argc, char* argv[])
{long long ii  10;func(reinterpret_castvoid *(ii));
}4.dynamic_cast 
动态转换dynamic_cast用于基类和派生类之间的转换但只能在运行时确定类型信息因此只能用于多态类型。如果转换失败将返回一个null指针。其语法如下 
dynamic_cast目标类型 (原始类型) 以下是几个具体例子: 
1、将一个基类指针强制转换为一个派生类指针: 
class Base { virtual void f(){} };
class Derived : public Base { void f(){} };
Base *b  new Derived(); // 基类指针指向派生类对象
Derived *p  dynamic_castDerived *(b); // 将基类指针转换为派生类指针2、使用 dynamic_cast 对指针进行类型判断 
class Base {};
class Derived : public Base {};Base* b1  new Derived();
Derived* d1  dynamic_castDerived*(b1);
if (d1 ! nullptr) {// b1 是 Derived 类型的。
}需要注意的是如果指向的基类指针并不真正指向派生类或者目标类型与原始类型之间的类型转换无法完成dynamic_cast会返回null指针或抛出std::bad_cast异常。因此在使用dynamic_cast时需要非常小心确保程序的健壮性和安全性。