C++类型转化关键字
2023-12-13 15:40:52
1.C 语言类型转化
void Test ()
{
//隐式类型转换
int i = 1;
double d = i;
printf("%d, %f\n", i, d);
//显式强制转换
int* ptr = &i;
int value = (int) p;
printf("%x, %d\n" , ptr, value);
}
2.C++的类型转化
C
语言的转换格式过于精简,有不少缺点的:
- 数据精度丢失
- 显式类型转换将所有情况混合在一起,代码不清晰
因此 C++
提出了类型转化风格,但因为 C++
要兼容 C
语言,所以 C++
中还可以使用 C
语言的转化风格,导致这一风格变成值得遵循的非硬性规则。
2.1.static_cast
编译器隐式执行的任何类型转换都可以使用 static_cast
,但它不能用于两个不相关的类型进行转换,这会引发编译器报错。
#include <iostream>
using namespace std;
int main()
{
double d = 12.34;
int a = static_cast<int>(d);//转化成功
cout << a << endl;
//int* p = static_cast<int*>(a);//转化失败
return 0;
}
2.2.reinterpret_cast
强制类型转化可以使用 reinterpret_cast
表明。
#include <iostream>
using namespace std;
int main()
{
double d = 12.34;
int a = static_cast<int>(d);//转化成功
cout << a << endl;
//int* p = static_cast<int*>(a);//转化失败
int* p = reinterpret_cast<int*>(a);//转化成功
cout << p << endl;
return 0;
}
2.3.const_cast
const_cast
最常用的用途就是删除变量的 const
属性,方便赋值,但是您需要注意一些“奇怪”的现象,免得坑到自己。
#include <iostream>
using namespace std;
void Test()
{
const int a = 10;
int* pa = const_cast<int*>(&a);
*pa = 3;
cout << a << endl;//由于 a 是一个常量,因此就会导致这里提前被替换为 10,还来不及被指针修改
cout << *pa << endl;
}
int main()
{
Test();
return 0;
}
2.4.dynamic_cast
可以将一个父类对象的“指针/引用”转换为子类对象的“指针/引用”(动态转换),避免危险的行为。
#include <iostream>
using namespace std;
class Father
{
public:
virtual void f() {}
};
class Son : public Father
{};
void fun(Father* pf)
{
//dynamic_cast 会先检查是否能转化成功,能成功转化,不能则返回 nullptr
//如果 pf 得到的是子类指针还好,但如果真的就是父类指针本身,转化为子类后就有可能会造成越界问题
Son* pb1 = static_cast<Son*>(pf);
Son* pb2 = dynamic_cast<Son*>(pf);
cout << "pb1:" << pb1 << " pb2:" << pb2 << endl;
}
int main()
{
Father f;
Son s;
fun(&f);
fun(&s);
return 0;
}
3.RTT机制
RTTI
即 Run-time Type identification
的简称,翻译为“运行时类型识别”。用于在运行时获取对象的实际类型信息,它允许程序在运行时判断对象的实际类型,以便进行相应的操作。而 C++
主要通过以下方式来支持 RTTI
:
-
typeid
运算符,用于获取变量或表达式的类型信息,但它并不能直接得到类型对应的字符串。typeid
返回的是std::type_info
类型的对象,代表被查询对象的类型信息。要将类型信息转换为字符串,通常需要使用type_info::name()
方法#include <iostream> #include <typeinfo> using namespace std; class Base { //... }; class Derived : public Base { //... }; int main() { Base* ptr1 = new Derived(); Derived* ptr2 = new Derived(); if (typeid(*ptr1) == typeid(Derived)) { cout << "YES" << endl; } if (typeid(*ptr2) == typeid(Derived)) { cout << "YES" << endl; } cout << typeid(ptr1).name() << endl; delete ptr1; delete ptr2; return 0; }
-
dynamic_cast
运算符,上面有介绍,这里不多说 -
decltype()
类型推导,auto
只能在声明的时候简化声明长度,而这个工具可以由用户放置任意表达式来推断表达式的类型,灵活定义变量的类型#include <iostream> #include <typeinfo> using namespace std; // 定义一个函数 func,返回类型为 int int func() { return 42; } int main() { //使用 decltype 推导出变量 a 的类型 //a 的类型为 int,与 func() 的返回类型相同 decltype(func()) a = 10; cout << typeid(a).name() << endl; return 0; }
文章来源:https://blog.csdn.net/m0_73168361/article/details/134898308
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!