C++每日一练(四种强制转换)

151 阅读2分钟

本文已参与「新人创作礼活动」,一起开启掘金创作之路。

一、今日课题

四种强制转换

二、实战演练

C++的四种强制类型转换为:static_cast、const_cast、reinterpret_cast和dynamic_cast

类型转换的一般形式:cast-name(expression);

1)有何用?

  • dynamic_cast 主要用于执行“安全的向下转型(safe downcasting)”,也就是说,要确定一个对象是否是一个继承体系中的一个特定类型。它是唯一不能用旧风格语法执行的强制转型,也是唯一可能有重大运行时代价的强制转型。

  • static_cast 可以被用于强制隐型转换(例如,non-const 对象转型为 const 对象,int 转型为 double,等等),它还可以用于很多这样的转换的反向转换(例如,void* 指针转型为有类型指针,基类指针转型为派生类指针),但是它不能将一个 const 对象转型为 non-const 对象(只有 const_cast 能做到),它最接近于C-style的转换

  • const_cast 一般用于强制消除对象的常量性。它是唯一能做到这一点的 C++ 风格的强制转型。

  • reinterpret_cast 是特意用于底层的强制转型,导致实现依赖(implementation-dependent)(就是说,不可移植)的结果,例如,将一个指针转型为一个整数。这样的强制转型在底层代码以外应该极为罕见。

2)怎么用?

  • static_cast: 编译器在编译期处理, 将地址a转换成类型T,T和a必须是指针、引用、算术类型或枚举类型
class A{ ... };
class B{ ... };
class D : public B{ ... };
void f(B *pb, D *pd)
{
	D *pd2 = static_cast<D*>(pb);            //不安全,pb可能只是B的指针
	B *pd2 = static_cast<B*>(pb);            //安全的
	A*pd2 = static_cast<A*>(pb);             //错误A与B没有继承关系
}

  • dynamic_cast :编译器在运行期,会检查这个转换是否可能,完成类层次结构中的提升.
class Base{virtual dummy() };
class Derived : public Base{};

Base*  b1 = new Derived;
Base*  b2 = new Base;

Derived* d1 = dynamic_cast<Derived *>(b1);        //succeed
Derived* d2 = dynamic_cast<Derived *>(b2);
  • const_cast :编译器在编译期处理,去掉类型中的常量
class A{ ...};
void f()
{
	const A *pa = new A;      //const对象
	A* pb;
	pb = const_cast<A*>(pa);
}

const char* p = "123";
char* c = const_cast<char*>(p);
c[0] = 1;

  • reinterpret_cast:编译器在编译期处理,任何指针都可以转换成其它类型的指针
class A{...};
class C{...};
void f()
{
	A* pa = new A;
	void* pv = reinterpret_cast<A*>(pa);
}

这里写图片描述