C++进阶1:xxx_cast类型转换

类型转换

隐式类型转换
显式类型转换

语法

xxx_cast <类型> (表达式)

1、static_cast

用于非多态类型之间的转换,不提供运行时的检查来确保转换的安全性。
主要有如下:
(1)基本数据类型转换
(2)int转换成enum
(3)基类和子类之间指针和引用的转换

上行转换:把子类的指针或引用转换成父类,这种转换是安全的(通常使用默认转换)。
下行转换:把父类的指针或引用转换成子类,这种转换是不安全的,也需要程序员来保证(通常使用dynamic_cast)。

1.1 基本数据类型转换

(1)int转换成char

int n = 97;
cout << n << '\t' << (char)n << '\t' << static_cast<char>(n) << endl;

(2)int转换成float

int n = 1;
cout << n/2 << '\t' << (float)n/2 << '\t' << static_cast<float>(n)/2 << endl;

1.2 int转换成enmu

enum Week{
   
   SUN,MON,TUE,WED,THU,FRI,SAT
};
Week day = 0;

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

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(0);可以消除上面的错误。

1.3 基类和子类之间指针和引用的转换

已知存在继承关系的两个类Base和Derive

class Base{
   
public:
    void Print(){
   cout << "Base" << endl;}
};
class Derive:public Base{
   
public:
    void Print(){
   cout << "Derive" << endl;}
};

(1)上行转换

// 对象
Derive d;
Base b = static_cast<Base>(d);
b.Print();

// 引用
Base& fb = static_cast<Base&>(d);
fb.Print();

// 指针
Base* pb = static_cast<Base*>(new Derive);
pb->Print();

通常使用隐式转换

// 对象
Derive d;
Base b = d;
b.Print();

// 引用
Base& fb = d;
fb.Print();

// 指针
Base* pb = new Derive;
pb->Print();

(2)下行转换

这种转换不安全,通常使用dynamic_cast。

1.4 指针/引用转换

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

void* pd = new Derive;
Base* pb = pd; //  error: invalid conversion from ‘void*’ to ‘Base*’
pb->Print();

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

2、const_cast

2.1 常见错误

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

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

2.2 const_cast作用

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);

2.3 注意

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

const int a = 10;
cout << "a:" << a << endl;
const_cast<int&>(a) = 11; // 已经改变a所在内存的值
cout << "a:" << a << endl; // 常量展开,看不到改变
cout << "*(&a)" << *(&a) << endl; // 直接访问内存可以看到改变 
int *p = &a;
cout << "*p:" << *p << endl; // 直接访问内存可以看到改变

2.4 在const成员函数中修改成员变量

(1)通常在const成员函数中是不能修改成员变量。
(2)在const函数中this指针是const类型,所以所有成员不能被直接改变。
例如:
提供一个打印出Set/Get次数的功能

#include <iostream>
using namespace std;

class Integer{
   
    int n;
    int setter;
    int getter;
public:
    Intege
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值