c++进阶1:xxx_cast类型转化

本文深入探讨了C++中的类型转换,包括隐式转换和显式转换,如`static_cast`、`const_cast`、`dynamic_cast`和`reinterpret_cast`。详细阐述了基本数据类型转换、指针和引用转换、常量转换,以及在基类与子类之间的转换。此外,还讨论了在成员函数中如何修改成员变量,并提供了相关的代码示例和错误处理策略。
摘要由CSDN通过智能技术生成

(***)1. 类型转换

c语言的转换;
(1)隐式转换(从表示范围小的类型转化为范围大的类型)
(2) 显示类型转化:强制类型转化;

 void*v = p;  //1.1 隐式转换
   p = (int*) v; //1.2显示类型转化;
xxx_cast <类型> (表达式)

一共有以下四种形式: static_castconst_cast, dynamic_cast,
reinterpret_cast,提供安全性的检测,在代码中更加醒目;

(***)1.1. static_cast

用于非多态类型之间的转换,不提供运行时的检查来确保转换的安全性。
主要有如下

  1. 基本数据类型转换
  2. int转换成enum
  3. 基类和子类之间指针和引用的转换
  • 上行转换,把子类的指针或引用转换成父类,这种转换是安全的(通常使用默认转换)。
  • 下行转换,把父类的指针或引用转换成子类,这种转换是不安全的,也需要程序员来保证(通常使用dynamic_cast)。

1.1.1 基本数据类型转换

  • int转换成char
  char c = 'a';
   cout << c << endl;
   cout << (int)c << endl;
   cout << static_cast<int>(c)<< endl;

1.1.2 int转换成enum

 enum BOOL{
   
    FALSE,TRUE
};
   BOOL b = static_cast<BOOL>(1==2);

编译上述代码出现如下错误:

  • g++编译错误:error: invalid conversion from ‘int’ to ‘Week’
  • clang++编译错误:error: cannot initialize a variable of type 'const Week' with an rvalue of type 'int'

把代码Week day = 0;改为Week day = static_cast<Week>(0);可以消除上面的错误。

1.1.3 指针/引用转换

void指针转换成目标类型的指针,这种转换是不安全的,也需要程序员来保证;
如下代码编译出错,因为不能把void*转换成其他具体指针。

 //2.2指针类型之间的转化;(pointer)
   int* arr1 = (int*)malloc(10*sizeof(int));
   int* arr2 = static_cast<int*>(malloc(10*sizeof(float)));
  

(完整代码见001_static.cpp)

#include <iostream>
using namespace std;


enum BOOL{
   
    FALSE,TRUE
};

int main()
{
   
   //1 c语言的转换;
   //1.1 隐式转换(从表示范围小的类型转化为范围大的类型)
   //1.2 显示类型转化:强制类型转化;
   int n = 10;
   float f = n;
   n =  f;  //截取

   int* p = &n;
   void*v = p;  //1.1 隐式转换
   p = (int*) v; //1.2显示类型转化;


   //2.1基本类型之间的转化;
   char c = 'a';
   cout << c << endl;
   cout << (int)c << endl;
   cout << static_cast<int>(c)<< endl;
   
   //2.2指针类型之间的转化;(pointer)

   int* arr1 = (int*)malloc(10*sizeof(int));
   int* arr2 = static_cast<int*>(malloc(10*sizeof(float)));
  
  //2.3 bool类型的转化;
   BOOL b = static_cast<BOOL>(1==2);
    cout << b << endl;

    return 0;
}

Base* pb = pd;改为Base* pb = static_cast<Base*>(pd);,可以解决上述编译错误。

static_cast跟传统小括号转换方式几乎是一致的。
问题:为什么要用static_cast代替传统小括号转换方式?

(***)1.2. const_cast

常量赋值给非常量时,会出现下面编译错误。

  const int a = 10;
    
    // 指针
    const int* cp = &a;
    int* p = cp;// error: invalid conversion from ‘const int*’ to ‘int*’
    
    // 引用
    const int& cf = a;
    int& f = cf;// error: binding ‘const int’ to reference of type ‘int&’ discards qualifiers

const_cast主要作用是移除类型的const属性。

  1. 常量指针被转化成非常量的指针,并且仍然指向原来的对象;
  2. 常量引用被转换成非常量的引用,并且仍然指向原来的对象;
  3. const_cast一般用于修改底指针。如const char *p形式。
const int a = 10;

// 指针
const int* cp = &a;
int* p = const_cast<int*>(cp);

// 引用
const int& cf = a;
int& f = const_cast<int&>(cf);

(***)1.2.1 在const成员函数中修改基本类型

  1. const_cast<><>中通常只用指针或者引用类型。
  2. 基本类型常量,因为存在常量展开的情况,const_cast<>并不会改变后面的值。

(1) 基本类型
<>里面不能用在基本类型,只能用指针和引用;;
基础类型onstc常量在使用展开操作,类似于在宏定义的展开(即a的值不变,但是内存的值改变啦)

 const int a = 10;
   //const_cast<int> a = 11; //(1.1)<>里面不能用在基本类型,只能用指针和引用;
   const_cast<int&>(a) = 12;  //(1.2)引用修改
   cout << &a << ":" << a << endl;  //(1.3)基础类型onstc常量在使用展开操作,类似于在宏定义的展开(即a的值不变,但是内存的值改变啦)

(2)不能修改的字符串对象

   const string s("abcd");
   cout << s << endl;
   const_cast<string&>(s) += "efg";

(3)不能修改的类的成员变量,返回引用和指针类型

 const Simple s1(100);
    cout << s1.Get() << endl;
    const_cast<Simple&>(s1).Set(110);
    cout << s1.Get() << endl;
    const Simple* ps1 = &s1;
    cout << ps1->Get() << endl;
    const_cast<Simple*>(ps1)->Set(120);
    cout << ps1->Get() << endl;

(完整代码见00201_const_cast.cpp)

#include 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值