使用说明
这些类型转换符号是C++中引入的,而C语言中是通过(NewType)方式进行类型转换的;
此外,对于这些转换的底层逻辑实现没有做深入探究,以后有机会再加。
- const_cast主要用于去除指针和引用中的const属性(注意不是类型之间转换,而是同一类型的const与非const之间转换)
- dynamic_cast 耗时,尽量不要用,可以通过设计来避免;并且虚函数不需要
- static_cast用于一般类型转换较多,而且作为const_cast反向操作
- reinterpret_cast 只改变对这它的类型解释,不改变底层二进制值,所以你翻译成啥就解释成啥 如果解释和实际存放的值不一致,就会导致读出的值错误–需要小心。
static_cast
- 和C语言中(newtype)强转是对应的,常用于基本类型之间的转换
- 注意他和reinterpret_cast的区别,这个是会改底层实际二进制表示的
- 可以将非const转为const, 也就是可以作为const_cast的反操作(反过来操作只能用const_cast)
- 也可以将父类指针转为子类指针,注意dynmaic_cast中说的情况–对于非虚函数的情况可能需要dynmaic_cast而不是static_cast
- static_cast<> 可能在运行时存在一些运行负担,这主要依赖于你转的类型。如果你转的类型是void* 或者非多态对象的层次结构,那么就没有运行时成本;如果你转换一个多态对象(比如子类转父类)可能会有存在偏移更改的消耗,因为vtable需要运行时确定。
const_cast1
- 用于去除常量中的const属性,但是作用的对象必须是指针,引用;
// 比如, tensorRT API中传入的inputs都是const指针,但是在使用的时候需要非const,则需要在使用前,去掉const
// 注意const_cast不能从const void* 直接转float*,因为它本身只是用于去const的,而不是不同类型之间转换的。
float* input_1 = const_cast<float*>(reinterpret_cast<const float*>(inputs[0]));
// 或者写成
float* input_1 = reinterpret_cast<float*>(const_cast<void*>(inputs[0]));
reinterpret_cast
- 其实可以直观的理解,也就是转换的只是特性解释,不改变底层二进制值。
- 根据上一条的理解,我们可以用reinterpret_cast将指针转化为数值;因为我们只是把这个指针的解释改变为size_t数据类型的解释,这样底层表示地址信息的二进制不动,则地址会被翻译成地址数值;这样就能看地址空间范围了。
- 这也解释了我们经常把无类型的指针void*转换为实际类型指针,也是底层二进制值不动,只是把变量的解释特性改变了,就可以按照指定类型去读从而翻译成真实的数据。
- reinterpret_cast 是一个纯编译器转换,所以在执行的时候是没有代价消耗的。
float* ptr = new float[2];
ptr[0] = 1;
ptr[1] = 2;
const size_t address_value = reinterpret_cast<size_t>(ptr); // 这样能看ptr本身地址的值
void* n = reinterpret_cast<void*>(ptr);
float* ptr_b = reinterpret_cast<float*>(n); // 这样是可以的,因为保持了对底层二进制的统一类型解释。
// 下面语句错误
int* a = reinterpret_cast<int*>(ptr);
std::cout<<a[0] <<std::endl; // 那么a[0]本来二进制是表示float值的,而上一个语句将其解释为int类型的二进制;则翻译出来实际打印的a[0]的值就不是1了。
- 转数组指针:
reinterpret_cast<Type (&)[num]> test将test指针转为数组指针。
dynmaic_cast
- 用来处理一种“安全的向下转换”,当父类指针指向它new出来的多个子类对象时,需要dynamic_cast进行安全转换
- dynamic_cast的执行速度比较耗时,在多重继承中最好不用,可以通过设计模式来代替类型转换。
- 用dynamic_cast向下转换的时候,如果转换失败,则返回NULL指针
- dynamic_cast是针对非虚函数的执行情况使用的,对于虚函数则不需要这种类型转换
#include <iostream>
#include <vector>
class Father{
public:
virtual void Function() {std::cout <<"Father"<< std::endl;}
};
class ChildrenA : public Father {
public:
virtual void Function() {}
void FunctionA() {std::cout <<"A"<< std::endl; }
};
class ChildrenB : public Father {
public:
virtual void Function() {}
void FunctionB() { std::cout <<"B"<< std::endl; }
};
int main() {
Father *test = new Father;
Father *testA = new ChildrenA;
Father *testB = new ChildrenB;
std::vector<Father*> test_list = {test, testA, testB};
for (auto it = test_list.begin(); it != test_list.end(); ++it) {
// 注意,当it不能转换为ChildrenA时,则返回NULL,则这个if条件为false不执行
if (ChildrenA* a = dynamic_cast<ChildrenA*>(*it)) {
a->FunctionA();
} else if (ChildrenB* b = dynamic_cast<ChildrenB*>(*it)) {
b->FunctionB();
} else {
(*it)->Function();
}
}
return 0;
}
reference
(https://blog.csdn.net/bajianxiaofendui/article/details/86616256) ↩︎
920

被折叠的 条评论
为什么被折叠?



