cast c语言,C++基础语法---四种cast操作符

C++中四种类型转换是:static_cast, dynamic_cast, const_cast, reinterpret_cast

const_cast

用于将const变量转为非const。const_cast中的类型必须是指针、引用或者指向对象类型成员的指针,主要是用来去掉const属性,当然也可以加上const属性。主要是用前者,后者很少用。核心:对地址的操作。

void const_cast_test()

{

class A

{

public:

A() : _num(0) {}

public:

int _num;

};

const int c_type = 100;

//auto var = const_cast(c_type); //非指针、引用,开发环境报错

//类指针

const A a;

const A *pa = &a;

//pa->_num = 10; //开发环境报错

A *pa2 = const_cast(pa);

pa2->_num = 11;

std::cout << "pa->_num=" << pa->_num << "; pa2->_num=" << pa2->_num << std::endl;

//pa->_num=11; pa2->_num=11

//基本数据类型

const int i = 3;

int *p = const_cast(&i);

*p = 10; //success

std::cout << "i=" << i << "; *p=" << *p << std::endl;

//i=3; *p=10

{

volatile const int i = 3;

int *p = const_cast(&i);

*p = 10; //success

std::cout << "second i=" << i << "; *p=" << *p << std::endl;

//second i=10; *p=10

}

//加上const属性

int j = 10;

const int *k = const_cast(&j); //一般可以直接写const int* k = &j;

if(0)

{

//对于本身定义为const的类型,应用const_cast去掉了const属性,然后再对这块内容进行write操作时,程序崩溃

const char* c_str = "hello world";

char* sz = const_cast(c_str);

sz[0] = 'H';

std::cout << "c_str =" << c_str<< "; sz =" << sz << std::endl;

//result---> Segmentation fault (core dumped)

}

}

static_cast

是最常用的转换,但是转换的时候不会检查类型来保证转换的安全性,因此安全性相对其他转换较低。需要注意的是:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。用于各种隐式转换,比如非const转const,void*转指针等, static_cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知。static_cast本质上是  传统c语言强制转换的替代品。核心:c语言强制转换。

void static_cast_test()

{

class base

{

};

class derived : public base

{

};

// 基本类型转换 float -> int

int i;

float f = 67.27f;

i = static_cast(f);

//子类 -> 父类

derived d;

base b = static_cast(d);

//父类 -> 子类

base bb;

derived *dd = static_cast(&bb); //compile error

base *pB = new base;

derived *pD = static_cast(pB); //编译通过,但是是******不安全的******(例如访问子类成员)

}

reinterpret_cast

即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。T必须是一个指针、引用、算术类型、函数指针或者成员指针。操作符用于将一种类型转换为另一种不同的类型,比如可以把一个整型转换为一个指针,或把一个指针转换为一个整型,因此使用该操作符的危险性较高,一般不应使用该操作符。

void reinterpret_cast_test()

{

class base

{

};

class derived : public base

{

};

class other

{

};

//1.不同类型之间的转换

//可以转,但是不安全

base* b1 = new derived;

other* o1 = reinterpret_cast(b1);//OK

//2.算术类型转指针

long l = 0;

base* b2 = reinterpret_cast(l);//OK

int i = 0;

b2 = reinterpret_cast(i);//OK

float f = 0.0;

//b2 = reinterpret_cast(f); //无法将浮点型变量进行reinterpret转换

char c = 'a';

b2 = reinterpret_cast(c);//OK

bool b = true;

b2 = reinterpret_cast(b);//OK

//3.指针转换为算术类型

base* b3 = new derived;

long l3 = reinterpret_cast(b3);

}

dynamic_cast

一、简介:将一个基类对象指针(或引用)cast (抛)到继承类指针,dynamic_cast 会根据基类指针是否真正指向继承类指针来做相应处理。二、返回值:对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针;对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。 三、注意:dynamic_cast在将父类cast到子类时,父类必须要有虚函数。即操作数中必须要有虚函数。四、原理:dynamic_cast<> 会用到RTTI技术。编译器都是通过vtable找到对象的RTTI信息的,如果基类没有虚方法,也就无法判断一个基类指针变量所指对象的真实类型。

void dynamic_cast_test()

{

class base

{

public:

virtual void print(){std::cout<

};

class derived : public base

{

public:

void print(){std::cout<

};

class other

{

public:

virtual void print(){std::cout<

};

//*************** 类无虚函数 ***************

//基类 -> 子类

base *pb0 = new base;

//derived *pd0 = dynamic_cast(pb0); //如果pb0无虚函数时,IDE检查出错, 操作数必须包含 虚函数

//不同类型的转换

//会转换失败

other* o2 = new other;

derived* pd2 = dynamic_cast(o2);

if(pd2 == nullptr){std::cout<

//基类 -> 子类

base *pb1 = new base;

derived *pd1 = dynamic_cast(pb1); //失败,pd1 = NULL

if(pd1 == nullptr){std::cout<

//子类 -> 子类

base *pb3 = new derived;

derived *pd3 = dynamic_cast(pb3); //成功

if(pd3 != nullptr){pd3->print();}

//子类 -> 基类

base *pb4 = new derived;

base *pd4 = dynamic_cast(pb4); //成功

if(pd4 != nullptr){pd4->print();}

}

标签:const,derived,dynamic,C++,---,cast,base,指针

来源: https://blog.csdn.net/weixin_36887247/article/details/109499936

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值