c++学习:隐式类型转换+explicit关键字+四种类型转换

本文详细介绍了C++中隐式类型转换的使用、explicit关键字的作用以及四种类型转换操作符(static_cast、reinterpret_cast、dynamic_cast、const_cast)的用法,包括它们的格式和实例,以帮助开发者避免误解和错误。
摘要由CSDN通过智能技术生成

目录

隐式类型转换

当定义一个字符串类

想新建一个对象有下面几种方式

但我不想用隐式类型转换得方式来新建,因为隐式转换成了分配若干字节的空字符串,容易令人误解,就要在构造函数前面用explicit关键字来修饰

explicit关键字的用途是  防止隐式转换行为来初始化对象

四种类型转换

4种类型转换操作符

 static_cast

格式

例子 int转换为char

reinterpret_cast

格式

例子  把int*强转为char*

dynamic_cast

格式

例子  新建一个基类和派生类,基类指针指向派生类对象,将基类指针还原成子类指针

const_cast

格式

例子  去除int*的const属性


隐式类型转换

当定义一个字符串类

class MyString
{
public:
    MyString(int n) {} 
    MyString(const char* p) {} 
private:
    char*m_ptr;
};

想新建一个对象有下面几种方式

正常新建对象
MyString s0("hello");
MyString s1 = MyString(10);
MyString s2(10);

用隐式转换新建对象
MyString s3 = "China";//等价于MyString s3 = MyString("China")
MyString s4 = 10;//分配10个字节的空字符串,等价于MyString s4 = MyString(10)
MyString s5 = 'A';//分配int('A')个字节的空字符串,等价于MyString s5 = MyString(4)

但我不想用隐式类型转换得方式来新建,因为隐式转换成了分配若干字节的空字符串,容易令人误解,就要在构造函数前面用explicit关键字来修饰

class MyString
{
public:
    //explicit 关键字的用途: 防止隐式转换行为来初始化对象
    explicit MyString(int n) {} 
    explicit MyString(const char* p) {} 
private:
    char*m_ptr;
};

explicit关键字的用途是  防止隐式转换行为来初始化对象

当声明了explicit后, 编译时就不会自动隐式转换,就会报错

四种类型转换

4种类型转换操作符

  • static_cast                        静态类型转换,如int转换为char  隐式类型转换
  • reinterpret_cast                重新编译类型,强制转换
  • dynamic_cast                   动态类型转换,子类和父类之间的多态类型转换
  • const_cast                        去除变量的只读属性

 static_cast

格式

转换之后该数据类型的变量 = static_cast<你要转换之后的数据类型>(你要转换的变量名)

例子 int转换为char

int val = 97;
//方式1
char ch = val;//val会进行隐式类型转换,当成 字符的ascii来进行处理
//方式2
char ch = static_cast<char>(val);

reinterpret_cast

格式

转换之后该数据类型的变量 = reinterpret_cast<你要转换之后的数据类型>(你要转换的变量名)

例子  把int*强转为char*

int val = 97;
//方式1
char *p = (char*)&val;
//方式2
char*p = reinterpret_cast<char*>(&val);

dynamic_cast

格式

转换之后该数据类型的变量 = dynamic_cast<你要转换之后的数据类型>(你要转换的变量名)

例子  新建一个基类和派生类,基类指针指向派生类对象,将基类指针还原成子类指针

class Base{
public:
    Base(){}
    //声明为虚析构,否则 dynamic_cast 动态转换失败
    virtual ~Base(){}
};
class Child1:public Base
{

};


//基类指针指向派生类对象
Base *b1 = new Child1;
//方法1 这种转换行为 会导致c1可能发生 内存越界(非法访问内存)
Child1 *c1 = (Child1*)b1;
//方法2 好处:更加标准化 动态类型转换行为会给你做 类型检查,因为有时候可能会存在转换失败的情况
//dynamic_cast 会给你做转换之后的类型检查,如果发现你转换之后,可能存在内存越界的情况,转换就会失败,给你返回NULL
Child1 *c2 = dynamic_cast<Child1*>(b1);
if(c2 == NULL)
{
    cout<<"dynamic_cast error"<<endl;
}
else{
    cout<<"dynamic_cast success"<<endl;
}

const_cast

格式

转换之后该数据类型的变量 = const_cast<你要转换之后的数据类型>(你要转换的变量名)

例子  去除int*的const属性

//去除const属性
int data = 10;
int *const p1 = &data;

//方法1
int*p2 = (int*)p1;
//方法2
int*p3 = const_cast<int*>(p1);

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值