【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;
}

目录
相关文章
|
1月前
|
设计模式 安全 算法
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
42 0
|
1月前
|
安全 编译器 程序员
特殊类设计以及C++中的类型转换
特殊类设计以及C++中的类型转换
28 2
|
1月前
|
安全 编译器 C++
【C/C++ 类型转换规则】一文了解C/C++ 中的类型转换规则,帮助你更好的编程
【C/C++ 类型转换规则】一文了解C/C++ 中的类型转换规则,帮助你更好的编程
19 0
|
4天前
|
安全 编译器 C语言
【C++高阶(九)】C++类型转换以及IO流
【C++高阶(九)】C++类型转换以及IO流
|
1月前
|
算法 Linux 编译器
【C++ 泛型编程 进阶篇】 C++ 模版元编程 类型转换 std::decay 全面教程
【C++ 泛型编程 进阶篇】 C++ 模版元编程 类型转换 std::decay 全面教程
43 0
|
1月前
|
安全 编译器 C语言
【C++ 类型转换关键字 *_cast 】理解const_cast、reinterpret_cast、dynamic_cast和static_cast的用法
【C++ 类型转换关键字 *_cast 】理解const_cast、reinterpret_cast、dynamic_cast和static_cast的用法
28 0
|
安全 编译器 程序员
【C++】—— C++的类型转换
【C++】—— C++的类型转换
|
1月前
|
安全 编译器 程序员
C++类型转换
C++类型转换
10 0
|
1月前
|
C++
c++类型转换
c++类型转换
63 1
|
2月前
|
存储 C++
C++ 操作重载与类型转换(二)
C++ 操作重载与类型转换(二)
42 2