【C++】类型转换

简介: 【C++】类型转换

static_cast

static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可以用。

static_cast不能用于两个不相关的类型进行转换。

double d = 12.34;
  int a = static_cast<int>(d);

reinterpret_cast

用于将一种类型转换为另外一种类型。

int a = 10;
  int* pa = static_cast<int*>(a);

这样是会报错的,因为从int类型转换到了int*,属于不相关的类型转换了。

这种情况下就只能使用reinterpret_cast了。

int a = 10;
  int* pa = reinterpret_cast<int*>(a);

const_cast

const_cast最常用的用途就是删除变量的const属性,方便赋值

const int a = 10;
  int* pa = const_cast<int*>(&a);
  *pa = 3;
  cout << a << endl;
  cout << *pa << endl;

但为什么输出是10和3呢?

因为编译器做了优化,直接把a的值存在寄存器当中了,虽然内存中a的值确实改变了,但是寄存器当中的没有改变,编译器他也不会去内存当中去找。

加上**volatile**关键字即可

volatile const int a = 10;
  int* pa = const_cast<int*>(&a);
  *pa = 3;
  cout << a << endl;
  cout << *pa << endl;

dynamic_cast

用于将一个父类对象的指针/引用转换为子类对象的指针或者引用。

向上转型:子类变为父类(不存在转换,编译器兼容)

向下转型:父类转换为子类

注意:

dynamic_cast只能用于父类含有虚函数的类。

dynamic_cast会检查是否能转换成功,不能会返回0。

父类要转换为子类是不被允许的,因为父类无法访问到子类的内容,会导致越界访问。

子类是可以转换为父类的,不存在越界行为。

class A
{
public:
  virtual void f(){}
public:
  int _a = 0;
};
class B : public A
{
public:
  int _b = 1;
};
// A*指针pa有可能指向父类,有可能指向子类
void fun(A* pa)
{
  // 如果pa是指向子类,那么可以转换,转换表达式返回正确的地址
  // 如果pa是指向父类,那么不能转换,转换表达式返回nullptr
  B* pb = dynamic_cast<B*>(pa); // 安全的
  //B* pb = (B*)pa;             // 不安全
  if (pb)
  {
    cout << "转换成功" << endl;
    pb->_a++;
    pb->_b++;
    cout << pb->_a << ":" << pb->_b << endl;
  }
  else
  {
    cout << "转换失败" << endl;
    pa->_a++;
    cout << pa->_a << endl;
  }
}
int main(void)
{
  A aa;
  B bb;
  fun(&aa);
  fun(&bb);
  return 0;
}

还有如下场景:

class A1
{
public:
  virtual void f(){}
public:
  int _a1 = 0;
};
class A2
{
public:
  virtual void f(){}
public:
  int _a2 = 0;
};
class B : public A1, public A2
{
public:
  int _b = 1;
};
int main(void)
{
  B bb;
  A1* ptr1 = &bb;
  A2* ptr2 = &bb;
  cout << ptr1 << endl;
  cout << ptr2 << endl << endl;
  B* pb1 = (B*)ptr1;
  B* pb2 = (B*)ptr2;
  cout << pb1 << endl;
  cout << pb2 << endl << endl;
  B* pb3 = dynamic_cast<B*>(ptr1);
  B* pb4 = dynamic_cast<B*>(ptr2);
  cout << pb3 << endl;
  cout << pb4 << endl << endl;
  return 0;
}

目录
相关文章
|
6月前
|
安全 编译器 程序员
【C++】C++的类型转换
【C++】C++的类型转换
|
6月前
|
设计模式 安全 算法
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
212 0
|
1月前
|
编译器 C语言 C++
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
C++入门4——类与对象3-1(构造函数的类型转换和友元详解)
19 1
|
1月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
29 3
|
1月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
44 3
|
6月前
|
存储 安全 编译器
C++:现代类型转换
C++:现代类型转换
49 5
|
1月前
|
C++
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
20 0
|
4月前
|
存储 安全 编译器
【C++11】类型转换
【C++11】类型转换
23 0
|
4月前
|
安全 程序员 编译器
C++一分钟之-C++中的类型转换
【7月更文挑战第8天】C++中的类型转换涉及隐式和显式操作,隐式转换如从`int`到`double`是自动的,但可能导致数据丢失。显式转换包括`static_cast`, `dynamic_cast`, `const_cast`, `reinterpret_cast`,以及转换构造函数。要避免数据丢失、类型不匹配和运行时错误,需谨慎使用显式转换并检查结果。过度使用`reinterpret_cast`应避免。理解这些转换有助于编写更安全的代码。
39 0
|
6月前
|
安全 程序员 C语言
从C语言到C++_37(特殊类设计和C++类型转换)单例模式(下)
从C语言到C++_37(特殊类设计和C++类型转换)单例模式
51 5