概述
C风格强制转换
即通过圆括号直接转型,常见有以下几种情况:
- 浮点数赋值给整型,舍弃小数部分(符合一般思维,可放心使用)
- 整数赋值给浮点型,数值不变,底层改用指数格式存储(符合一般思维,可放心使用)
- double型小数赋值给float型小数,精度略微损失,可能出现数值范围溢出(小心使用)
- 字符赋值给整数型,保留原字节数据,因为字符本身就是用ASCII码表示的,本质就是八位的较小整数(理解字符的存储方式,就很容易接受)
- 整数赋值给字符型,截断高地址数据,只保留低地址的八位,因为char型最多只有八位(小心使用)
- 有符号整数赋值给无符号整数,将包括符号在内的全部字节的直接赋值,实际数值会改变(小心使用)
- 无符号整数赋值给有符号整数,也是将包括符号在内的全部字节的直接赋值,但是数值可能会改变(小心使用)
- unsigned int和int字节存储区别:unsigned int和int位数是一样的,但是int将首个bit位作为正负号,0表示正数,1表示负数。unsigned int和int之间都是以字节的方式相互赋值。当字节以0开头时,它们表示的数值是相同的,当字节以1开头时,它们则分别表示整数和负数。由于int将首位作为符号位,因此它实际能表示的最大正整数只有unsigned int的一半
static_cast静态转换
类似C风格的强制转换,只允许在有关联的指针类型或基本类型间使用
比如基类指针和子类指针,int和double,对象指针和void指针
int main() {
double a = 1099.255;
int b = static_cast<int>(a);
char c[] = "hello";
string d = static_cast<string>(c);
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
return 0;
}
dynamic_cast动态转换
用于基类指针和子类指针之间的转换
虽然static_cast也具备这样的功能,但是是不安全的,dynamic_cast则会在转型时判断类型,如果类型不符则返回nullptr
由于类型信息是保存在虚函数表中的,因此dynamic_cast操作的基类必须包含virtual函数
不要觉得这个限制很麻烦,因为dynamic_cast的定位就是在多态场景下使用的
class Animal {
virtual void speak() {}
};
class Cat : public Animal {
void speak() {}
};
class Dog : public Animal {
void speak() {}
};
int main() {
Cat *a = new Cat;
Animal *b = dynamic_cast<Animal *>(a);
Cat *c = dynamic_cast<Cat *>(b);
Dog *d = dynamic_cast<Dog *>(b);
cout << a << endl;
cout << b << endl;
cout << c << endl;
cout << d << endl;
return 0;
}
reinterpret_cast重译转换
reinterpret_cast用于将地址,强制转换为任意类型的指针
顾名思义,reinterpret_cast就是不改变指针地址,但是强制将地址处的内存字节解释为某种类型的数据
class Object {
public:
char h = 'H';
char i = 'I';
char j = 'J';
int m = 100;
int n = 200;
int k = 300;
int x = 400;
int y = 500;
int z = 600;
};
int main() {
Object a;
double *b = reinterpret_cast<double *>(&a);
bool *c = reinterpret_cast<bool *>(&a);
char *d = reinterpret_cast<char *>(&a);
int *e = reinterpret_cast<int *>(&a);
int *f = reinterpret_cast<int *>(&a.m);
cout << &a << endl;
cout << *b << endl;
cout << *c << endl;
cout << *d << endl;
cout << d[1] << endl;
cout << d[2] << endl;
cout << *e << endl;
cout << *f << endl;
return 0;
}
const_cast常量转换
const_cast用于常量指针和非常量指针间的转换,同样适用于引用
函数和模块接口,由于会暴漏给很多文件或代码使用,难免会遇到需要修改const属性的情况,因为凡事总有特例,不可能一个接口适用于所有情景
即便是在单个文件中,我们也可能希望某个变量在大多时候值不被修改,但是在某个特定地方却又必须修改它的值,这时const_cast就派上用场了
const_cast提供了一个解决特殊需求的捷径,但是不应当滥用,否则const属性就失去意义了
int *getValue() {
return new int(10);
}
int main() {
//const转非const
int a = 100;
//定义一个指针pa,我们希望通过它来访问a,但是不希望它修改a的值,所以定义为const int *
const int *pa = &a;
//之后我们遇到一个特殊情况,必须得修改a的值,所以我们临时去除pa的const属性,赋值给pb
int *pb = const_cast<int *>(pa);
//通过pb修改a的值,完成其特殊使命后,我们应当继续使用pa
//注意,这里的a并不是const的,否则我们将无法修改a的数值
//我们只是将pa定义为const,禁止pa修改a的值而已
*pb = 200;
pb = nullptr;
//测试a的值
cout << a << endl;
//非const转const
//我们不希望函数的返回值被修改,所以将其转为const的
const int *pe = const_cast<const int *>(getValue());
return 0;
}
最后
以上就是清爽大树为你收集整理的【C++】【类型转换】C++类型转换的五种方式的全部内容,希望文章能够帮你解决【C++】【类型转换】C++类型转换的五种方式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复