[C++特殊操作符] 类型转换static_cast/const_cast/reinterpret_cast/dynamic_cast

文章目录

  • 使用说明
  • static_cast
  • const_cast[^1]
  • reinterpret_cast
  • dynmaic_cast
  • reference

使用说明

这些类型转换符号是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

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*转换为实际类型指针,也是底层二进制值不动,只是把变量的解释特性改变了,就可以按照指定类型去读从而翻译成真实的数据。
float* ptr = new float[2];
ptr[0] = 1;
ptr[1] = 2;
const size_t address_value = reinterpret_cast(ptr); // 这样能看ptr本身地址的值
void* n = reinterpret_cast(ptr);
float* ptr_b = reinterpret_cast(n); // 这样是可以的,因为保持了对底层二进制的统一类型解释。
// 下面语句错误
int* a = reinterpret_cast(ptr);
std::cout<

dynmaic_cast

  • 用来处理一种“安全的向下转换”,当父类指针指向它new出来的多个子类对象时,需要dynamic_cast进行安全转换
  • dynamic_cast的执行速度比较耗时,在多重继承中最好不用,可以通过设计模式来代替类型转换。
  • 用dynamic_cast向下转换的时候,如果转换失败,则返回NULL指针
  • dynamic_cast是针对非虚函数的执行情况使用的,对于虚函数则不需要这种类型转换
#include 
#include 

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


  1. (https://blog.csdn.net/bajianxiaofendui/article/details/86616256) ↩︎

你可能感兴趣的:(代码规范,C++基础,类型转换)