首页 > 试题广场 >

说一说c++中四种cast转换

[问答题]

const_cast可以消去变量类型中的constvolatile。可以利用它来改const变量的值,但是修改const变量是未定义行为,不要这么做。
static_cast是静态类型转换,一般代码中用得最多的就是它,可以用来转换常量类型,或者子类指针/引用转父类。C++里void*T*就要用它(C++禁止void*隐式转换为其他类型指针,反之可以。C语言二者都允许)
reinterpret_cast是在二进制层面上将值按照新类型重新解释,比方说查看指针地址的整数值就用cout << reinterpret_cast<std::uintptr_t>(some_ptr),又或者想直接操纵浮点数的二进制就用reinterpret_cast<std::int32_t&>(some_float)。它非常危险,少用
dynamic_cast使用了RTTI来做类型检查,父类转子类的时候使用它更安全。如果是不能转换的类型,转引用会抛std::bad_cast异常,转指针会返回nullptr。用得非常少,因为一用就会引入RTTI,造成代码膨胀。而且需要根据实际类型作出行动可以抽象成虚函数,不需要cast。

发表于 2019-08-28 15:04:51 回复(0)
C++中四种类型转换是:static_cast, dynamic_cast, const_cast, reinterpret_cast
1、const_cast

用于将const变量转为非const

2、static_cast

用于各种隐式转换,比如非const转const,void*转指针等, static_cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知;

3、dynamic_cast

用于动态类型转换。只能用于含有虚函数的类,用于类层次间的向上和向下转化。只能转指针或引用。向下转化时,如果是非法的对于指针返回NULL,对于引用抛异常。要深入了解内部转换的原理。

向上转换:指的是子类向基类的转换

向下转换:指的是基类向子类的转换

它通过判断在执行到该语句的时候变量的运行时类型和要转换的类型是否相同来判断是否能够进行向下转换。

4、reinterpret_cast

几乎什么都可以转,比如将int转指针,可能会出问题,尽量少用;
发表于 2021-02-17 15:31:55 回复(0)

1. static_cast

  • 定义和基本用途:static_cast是一种编译时期的类型转换操作符。它主要用于在相关类型之间进行转换,这些相关类型包括但不限于基本数据类型(如int和float)、类层次结构中的向上转型(将派生类指针或引用转换为基类指针或引用)和向下转型(将基类指针或引用转换为派生类指针或引用,但这种向下转型有一定风险)。
  • 示例代码 - 基本数据类型转换
int a = 10; float b = static_cast<float>(a); 

在这个例子中,static_cast将int类型的变量a转换为float类型并赋值给b。这种转换是比较安全的,因为从int到float的转换在数值表示上是合理的,只是数据精度可能会发生变化。

  • 示例代码 - 类层次结构向上转型
class Base {}; class Derived : public Base {}; Derived d; Base* b = static_cast<Base*>(&d); 

这里将派生类Derived的对象d的地址转换为基类Base的指针b。这是一种向上转型,在类层次结构中是安全的,因为派生类对象通常包含了基类对象的所有属性和行为。

  • 向下转型的风险和注意事项:当进行向下转型(从基类指针或引用转换为派生类指针或引用)时,static_cast不会进行运行时检查。如果转换不当,可能会导致程序运行时出现错误。例如:
class Base {};  class Derived : public Base {}; Base b; Derived* d = static_cast<Derived*>(&b); 

这里试图将基类Base对象的地址转换为派生类Derived的指针,这是不安全的,因为基类对象可能不包含派生类特有的成员,这种转换可能会导致访问非法内存区域等问题。

2. dynamic_cast

  • 定义和基本用途:dynamic_cast主要用于在类的继承层次结构中进行安全的向下转型。它是一种运行时类型检查的转换操作符。只有当被转换的对象实际上是目标类型(或者是目标类型的派生类)时,转换才会成功。
  • 示例代码 - 安全的向下转型
class Base { virtual void func() {} }; class Derived : public Base {}; Base* b = new Derived(); Derived* d = dynamic_cast<Derived*>(b); if (d!= nullptr) { // 转换成功,说明b指向的对象实际上是Derived类型或者其派生类型 } 

在这个例子中,首先创建了一个Derived类的对象,并通过基类指针b来指向它。然后使用dynamic_cast将基类指针b转换为派生类指针d。如果b指向的对象确实是Derived类型或者其派生类型,那么d将不为nullptr,表示转换成功;否则,d将为nullptr,表示转换失败。

  • 与static_cast在向下转型的对比:与static_cast不同,dynamic_cast会在运行时检查对象的实际类型,避免了不安全的向下转型。如果转换失败,会返回nullptr(对于指针类型的转换)或者抛出std::bad_cast异常(对于引用类型的转换)。

3. const_cast

  • 定义和基本用途:const_cast用于去除变量的const或volatile限定符。它主要用于在需要修改一个原本被声明为const的对象时,前提是这个对象本身在定义时没有被真正的const语义所限制(例如,通过一个非const指针指向一个const对象,然后使用const_cast来修改这个对象,这种做法虽然在语法上可行,但在语义上可能是不正确的,应该谨慎使用)。
  • 示例代码 - 去除const限定符
void func(const int* p) {  int* nonConstP = const_cast<int*>(p);  *nonConstP = 10; } int main() { const int a = 5; func(&a); return 0; } 

在这个例子中,函数func接收一个const指针p,然后使用const_cast将其转换为非const指针nonConstP,并修改了指针所指向的值。不过这种做法可能会导致未定义行为,因为a是一个真正的const变量,修改它违反了const的语义。正确的做法是只有当对象本身在定义时没有被真正的const语义所限制时,才可以使用const_cast来合理地修改对象。

4. reinterpret_cast

  • 定义和基本用途:reinterpret_cast是一种比较危险的类型转换操作符,它可以将一种类型的指针或引用转换为另一种几乎任意类型的指针或引用。这种转换只是简单地重新解释了内存中的数据,不进行任何类型检查,也不保证转换后的结果在语义上是合理的。
  • 示例代码 - 指针类型转换
int a = 10; char* p = reinterpret_cast<char*>(&a); 

在这个例子中,reinterpret_cast将int类型变量a的地址转换为char类型的指针p。这种转换后的指针操作需要非常小心,因为它可能会导致访问非法内存区域或者错误地解释数据。例如,使用p来访问内存就好像内存中存储的是char类型的数据,而实际上它原本是int类型的数据。

  • 注意事项和风险:由于reinterpret_cast几乎可以进行任意类型的转换,所以在使用时要特别谨慎。它可能会导致程序崩溃、数据损坏或者产生未定义行为。一般只有在非常特殊的情况下,如与底层硬件接口或者一些特殊的库函数交互时,并且清楚地知道转换的后果时,才会使用这种类型的转换。
发表于 2024-10-22 22:35:46 回复(0)
const_cast,它可以把cons变量改为非const。 static_cast,它转换基本类型,比如int转char,类的上下级转换都行,基类转子类不安全。 reinterpret_cast,它可以乱转,随意,出错别怪我,不安全,没有类型检查。 dyunamic_cast,类的子类转基类(安全),基类转子类,会检查运行时类型信息,信息位于虚函数表中,所以要有虚函数。 c++禁止void*转其它类型,反之可以,所以可以用static_cast来void*转为其它类型
编辑于 2020-09-02 22:51:50 回复(0)