C++四种类型转换的关键字及其特点

C++的四种强制类型转换,所以C++不是类型安全的。

关键字分别为:static_cast , dynamic_cast , const_cast , reinterpret_cas

使用C风格的强制转换可以把想要的任何东西转换成合乎心意的类型。那为什么还需要一个新的C++类型的强制转换呢?

新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。C++中风格是static_cast<type>(content)。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。程序员只要扫一眼这样的代码,就能立即知道一个强制转换的目的。

四种转换的区别:

static_cast:可以实现C++中内置基本数据类型之间的相互转换。

例:

int c=static_cast<int>(7.987); 
如果涉及到类的话,static_cast只能在有 相互联系的类型 中进行相互转换, 不一定包含虚函数

class A 
{}; 
class B:public A 
{}; 
class C 
{}; 

int main() 
{ 
    A* a=new A; 
    B* b; 
    C* c; 
    b=static_cast<B>(a);  // 编译不会报错, B类继承A类 
    c=static_cast<B>(a);  // 编译报错, C类与A类没有任何关系 
    return 1; 
}


const_cast: const_cast操作不能在不同的种类间转换。相反,它仅仅把一个它作用的表达式转换成常量。它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。那么,什么情况下需要消除一个const变量的const特性呢?比如,有时候有的函数的形参类型为非const类型,那么如果你要将一个const类型的参数传入就会报错。所以在这种情况下需要先使用const_cast转化一下。


reinterpret_cast: 有着和C风格的强制转换同样的能力。它可以转化任何内置的数据类型为其他任何的数据类型,也可以转化任何指针类型为其他的类型。它甚至可以转化内置的数据类型为指针,无须考虑类型安全或者常量的情形。不到万不得已绝对不用。
dynamic_cast: 
(1)其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。
(2)不能用于内置的基本数据类型的强制转换。
(3)dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。
(4)使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过。
        B中需要检测有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的情况,此时转换才有意义。 
        这是由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object model>)中,只有定义了虚函数的类才有虚函数表。
 (5)在类的转换时,在类层次间进行上行转换时(即指向子类对象的父类指针转换为指向子类对象的子类指针),dynamic_cast和static_cast的效果是一样的。在进行下行转换时(即指向父类对象的父类指针转换为指向子类对象的子类指针),dynamic_cast具有类型检查的功能,比static_cast更安全。即要转换的指针指向的对象的实际类型与转换以后的对象类型一定要相同,否则转换失败。
例:

#include<iostream> 
#include<cstring> 
using namespace std; 
class A 
{ 
   public: 
   virtual void f() 
   { 
       cout<<"hello"<<endl; 
       }; 
}; 

class B:public A 
{ 
    public: 
    void f() 
    { 
        cout<<"hello2"<<endl; 
        }; 

}; 

class C 
{ 
  void pp() 
  { 
      return; 
  } 
}; 

int fun() 
{ 
    return 1; 
} 
int main() 
{ 
    A* a1=new B;//a1是A类型的指针指向一个B类型的对象 
    A* a2=new A;//a2是A类型的指针指向一个A类型的对象 
    B* b; 
    C* c; 
    b=dynamic_cast<B*>(a1);//结果为not null,向下转换成功,a1之前指向的就是B类型的对象,所以可以转换成B类型的指针。 
    if(b==NULL) 
    { 
        cout<<"null"<<endl; 
    } 
    else
    { 
        cout<<"not null"<<endl; 
    } 
    b=dynamic_cast<B*>(a2);//结果为null,向下转换失败 
    if(b==NULL) 
    { 
        cout<<"null"<<endl; 
    } 
    else
    { 
        cout<<"not null"<<endl; 
    } 
    c=dynamic_cast<C*>(a);//结果为null,向下转换失败 
    if(c==NULL) 
    { 
        cout<<"null"<<endl; 
    } 
    else
    { 
        cout<<"not null"<<endl; 
    } 
    delete(a); 
    return 0; 
}













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C++中的所有关键字及其作用: 1. `auto`: 自动类型推导。 2. `break`: 终止循环或 switch 语句。 3. `case`: switch 语句中的分支。 4. `catch`: 捕获异常。 5. `char`: 字符类型。 6. `class`: 定义类。 7. `const`: 声明常量,或者表示函数不会修改对象。 8. `continue`: 跳过当前循环中的剩余代码。 9. `default`: switch 语句中的默认分支。 10. `delete`: 删除对象或释放动态分配的内存。 11. `do`: 循环语句,至少执行一次。 12. `double`: 双精度浮点数类型。 13. `dynamic_cast`: 运行时类型转换。 14. `else`: if 语句的分支。 15. `enum`: 枚举类型。 16. `explicit`: 显式构造函数或类型转换。 17. `export`: 指定函数或变量可在其他文件中使用。 18. `extern`: 声明变量或函数在其他文件中定义。 19. `false`: 布尔值假。 20. `float`: 单精度浮点数类型。 21. `for`: 循环语句。 22. `friend`: 友元函数或类。 23. `goto`: 跳转到标记的位置。 24. `if`: 条件语句。 25. `inline`: 内联函数。 26. `int`: 整数类型。 27. `long`: 长整数类型。 28. `mutable`: 声明类成员变量可修改。 29. `namespace`: 命名空间。 30. `new`: 分配动态内存。 31. `operator`: 自定义运算符。 32. `private`: 类访问控制,只能在类内部访问。 33. `protected`: 类访问控制,派生类可访问。 34. `public`: 类访问控制,任何地方都可访问。 35. `register`: 声明寄存器变量。 36. `reinterpret_cast`: 指针类型转换。 37. `return`: 返回函数值。 38. `short`: 短整数类型。 39. `signed`: 带符号整数类型。 40. `sizeof`: 获取类型或变量的大小。 41. `static`: 静态变量或函数,只在当前文件中可见。 42. `static_cast`: 静态类型转换。 43. `struct`: 定义结构体。 44. `switch`: 多分支选择语句。 45. `template`: 模板类或函数。 46. `this`: 指向当前对象的指针。 47. `throw`: 抛出异常。 48. `true`: 布尔值真。 49. `try`: 异常处理语句。 50. `typedef`: 定义类型别名。 51. `typeid`: 获取对象类型信息。 52. `typename`: 指示后面的标识符是类型名。 53. `union`: 联合类型。 54. `unsigned`: 无符号整数类型。 55. `using`: 声明命名空间中的符号。 56. `virtual`: 虚函数。 57. `void`: 空类型。 58. `volatile`: 声明变量可能被意外修改。 59. `wchar_t`: 宽字符类型。 以上是C++中的所有关键字及其作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值