首页 > 试题广场 >

四种cast转换

[问答题]
c++官方说明文档说的很清楚了,这些所谓标准答案都不标准
编辑于 2020-05-18 14:21:56 回复(0)

参考了C++官方说明文档


C++中四种类型转换是:static_cast、dynamic_cast、const_cast、reinterpret_cast

1、const_cast

通常用来设置或者移除指针所指向对象的const。
// const_cast
#include <iostream>
using namespace std;
void print (char * str) {
  cout << str << endl;
}
int main () {
  const char * c = "sample text";
  print ( const_cast<char *> (c) );
  return 0;
}

2、dynamic_cast

只能够用在指向类的指针或者引用上(或者void*)。这种转换的目的是确保目标指针类型所指向的是一个有效且完整的对象。

同隐式转换一样,这种转换允许upcast(从派生类向基类的转换)。但dynamic_cast 也能downcast(从基类向派生类的转换)当且仅当转过去的指针所指向的目标对象有效且完整。

// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;

class CBase { virtual void dummy() {} };
class CDerived: public CBase { int a; };

int main () {
  try {
    CBase * pba = new CDerived;
    CBase * pbb = new CBase;
    CDerived * pd;

    pd = dynamic_cast<CDerived*>(pba);
    if (pd==0) cout << "Null pointer on first type-cast" << endl;

    pd = dynamic_cast<CDerived*>(pbb);
    if (pd==0) cout << "Null pointer on second type-cast" << endl;

  } catch (exception& e) {cout << "Exception: " << e.what();}
  return 0;
}

3、static_cast

能够完成指向相关类的指针上的转换。upcast和downcast都能够支持,但不同的是,并不会有运行时的检查来确保转换到目标类型上的指针所指向的对象有效且完整。因此,这就完全依赖程序员来确保转换的安全性。但反过来说,这也不会带来额外检查的开销。
class CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<CDerived*>(a);
也可以用于执行任何其他也可以隐式执行的非指针转换,
double d=3.14159265;
int i = static_cast<int>(d); 
4、reinterpret_cast

能够完成任意指针类型向任意指针类型的转换,即使它们毫无关联。该转换的操作结果是出现一份完全相同的二进制复制品,既不会有指向内容的检查,也不会有指针本身类型的检查。

reinterpret_cast也能够完成指针向整数的转换。不过该整数的类型取决于平台。唯一的保证是该整数的类型能够容纳下指针的值以及能够再次被转换成一个有效的指针。

基本上reinterpret_cast能做但static_cast不能做的转换大多都是一些基于重新解释二进制的底层操作,因此会导致代码限定于特定的平台进而导致差移植性。

class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a);
编辑于 2020-08-19 15:26:35 回复(0)

①reinterpret_cast:类型转换函数将一个类型的指针转换为另一个类型的指针。这种转换不需要修改指针变量值数据存放格式,只需在编译时重新编译解释指针的类型即可。

double d = 9.3;

double *pd = &d;

int *pi = reinterpret_cast<int*>(pd);

但是不能用于非指针类型的转换。同隐式转换一样,reinterpret_cast也不能将一个const指针转换为void*指针。

②const_cast:用于去除指针变量的常量属性,将它转换为一个对应指针类型的普通变量。也可以将一个非常量的指针变量转换为一个常指针变量,在编译期间做出类型更改。

const int* pci = 0;

int* pj = const_cast<int*>(pci);

③static_cast:用于基本类型之间和具有继承关系的类型之间的转换,这种转换一般会更改变量的内部表示方式。

class Base();

class Derived :public Base {}

Derived d;

Base d = static_cast<Base>(d);

可将继承类对象转换为基类对象。但是反过来不行。

【注意】基类指针转换为继承类指针,在一定的危害性。

④dynamic_cast:与static_cast相对,是动态dynamic_cast转换。这种转换是在运行时进行转换分析的,并非在编译时进行。只能在继承类对象的指针之间或引用之间进行类型转换。进行转换时,会根据当前(RTTI)判断类型对象之间的转换是否合法。dynamic_cast转换失败,是通过是否为null指针检测;引用转换失败,抛出bad_cast异常。
将继承类指针或引用转换为基类指针或引用可以,反过来一般不行;但是如果基类中有虚函数也可以,也就是说被转换的类具有虚函数的对象指针时,编译也通过。

class Base();

class Derived :public Base {}

Derived *pd = new Derived;

Base *d = dynamic_cast<Base*>(pd);

编辑于 2019-07-08 20:59:54 回复(1)
1.static_const:实现C++内置基本类型的转换 2.const_const:实现const属性转换 3.reinterrupt_const:实现基本类型,指针或是基本类型到指针,无需考虑安全问题,一般不使用 4.、dynamic_cast: (1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。 (2)不能用于内置的基本数据类型的强制转换。 (3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。 (4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。 需要检测有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义。 这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念)中, 只有定义了虚函数的类才有虚函数表。 (5) 在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。在进行下行转换 时,dynamic_cast具有类型检查的功能,比 static_cast更安全。向上转换即为指向子类对象的向下转换,即将父类指针转化子类指针。向下转换的成功与否还与将要转换的类型有关,即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。
发表于 2019-02-17 08:19:52 回复(0)