C++中的数据类型强制转换

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++中的数据类型强制转换相关的知识,希望对你有一定的参考价值。

int b = 12;
short c = 0;
c = (short)b;

int b = 12;
short c = 0;
c = short(b);

这两种强制转换有什么区别吗?


C  风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:



TYPE b = (TYPE)a


C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。


const_cast,字面上理解就是去const属性。

static_cast,命名上理解是静态类型转换。如int转换成char。

dynamic_cast,命名上理解是动态类型转换。如子类和父类之间的多态类型转换。

reinterpreter_cast,仅仅重新解释类型,但没有进行二进制的转换。

4种类型转换的格式,如:



TYPE B = static_cast(TYPE)(a)


const_cast


去掉类型的const或volatile属性。



struct SA 

int i;

;

const SA ra;

//ra.i = 10; //直接修改const类型,编译错误

SA &rb = const_castSA&>(ra);

rb.i = 10;


static_cast


类似于C风格的强制转换。无条件转换,静态类型转换。用于:

1. 基类和子类之间转换:其中子类指针转换成父类指针是安全的;但父类指针转换成子类指针是不安全的。(基类和子类之间的动态类型转换建议用dynamic_cast)

2. 基本数据类型转换。enum, struct, int, char, float等。static_cast不能进行无关类型(如非基类和子类)指针之间的转换。

3. 把空指针转换成目标类型的空指针。

4. 把任何类型的表达式转换成void类型。

5. static_cast不能去掉类型的const、volitale属性(用const_cast)。



int n = 6;

double d = static_castdouble>(n); // 基本类型转换

int *pn = &n;

double *d = static_castdouble *>(&n) //无关类型指针转换,编译错误

void *p = static_castvoid *>(pn); //任意类型转换成void类型


dynamic_cast


有条件转换,动态类型转换,运行时类型安全检查(转换失败返回NULL):

1. 安全的基类和子类之间转换。

2. 必须要有虚函数。

3. 相同基类不同子类之间的交叉转换。但结果是NULL。



class BaseClass 

public:

int m_iNum;

virtual void foo();

//基类必须有虚函数。保持多台特性才能使用dynamic_cast

;

class DerivedClass: public BaseClass 

public:

char *m_szName[100];

void bar();

;

BaseClass* pb = new DerivedClass();

DerivedClass *pd1 = static_castDerivedClass *>(pb);

//子类->父类,静态类型转换,正确但不推荐

DerivedClass *pd2 = dynamic_castDerivedClass *>(pb);

//子类->父类,动态类型转换,正确

BaseClass* pb2 = new BaseClass();

DerivedClass *pd21 = static_castDerivedClass *>(pb2);

//父类->子类,静态类型转换,危险!访问子类m_szName成员越界

DerivedClass *pd22 = dynamic_castDerivedClass *>(pb2);

//父类->子类,动态类型转换,安全的。结果是NULL


reinterpreter_cast


仅仅重新解释类型,但没有进行二进制的转换:

1. 转换的类型必须是一个指针、引用、算术类型、函数指针或者成员指针。

2. 在比特位级别上进行转换。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。但不能将非32bit的实例转成指针。

3. 最普通的用途就是在函数指针类型之间进行转换。

4. 很难保证移植性。



int doSomething()return 0;;

typedef void(*FuncPtr)();

//FuncPtr is 一个指向函数的指针,该函数没有参数,返回值类型为 void

FuncPtr funcPtrArray[10];

//10个FuncPtrs指针的数组 让我们假设你希望(因为某些莫名其妙的原因)把一个指向下面函数的指针存入funcPtrArray数组:

funcPtrArray[0] = &doSomething;

// 编译错误!类型不匹配,reinterpret_cast可以让编译器以你的方法去看待它们:funcPtrArray

funcPtrArray[0] = reinterpret_castFuncPtr>(&doSomething);

//不同函数指针类型之间进行转换


总 结


去const属性用const_cast。

基本类型转换用static_cast。

多态类之间的类型转换用daynamic_cast。

不同类型的指针类型转换用reinterpreter_cast。

参考技术A 1、C++的四种强制类型转换,所以C++不是类型安全的。
分别为:static_cast , dynamic_cast , const_cast , reinterpret_cast
2、四种转换的区别:
static_cast:可以实现C++中内置基本数据类型之间的相互转换。
const_cast: const_cast操作不能在不同的种类间转换。相反,它仅仅把一个它作用的表达式转换成常量。它可以使一个本来不是const类型的数据转换成const类型的,或者把const属性去掉。
reinterpret_cast: 有着和C风格的强制转换同样的能力。它可以转化任何内置的数据类型为其他任何的数据类型,也可以转化任何指针类型为其他的类型。它甚至可以转化内置的数据类型为指针,无须考虑类型安全或者常量的情形。不到万不得已绝对不用。
dynamic_cast: 其他三种都是编译时完成的,dynamic_cast是运行时处理的,运行时要进行类型检查。不能用于内置的基本数据类型的强制转换。dynamic_cast转换如果成功的话返回的是指向类的指针或引用,转换失败的话则会返回NULL。使用dynamic_cast进行转换的,基类中一定要有虚函数,否则编译不通过
参考技术B (type)var 这种是从C里继承下来的叫C-Style cast, C风格转换, 只可用于内置类型之间的转换.

type(var)是C++加入的叫Function-Style cast, 函数式转换, 用于内置类型时和C-Style cast效果相同, 但它还可以用于类与内置类型, 类与类之间的转化, 如:

cout << string("123").size();

则只可以用函数式转化, 你不能:

cout << (string)"123".size();

另外C++中还有其自带的C++专用cast:
static_cast, const_cast, dynamic_cast, reinterpret_cast.本回答被提问者采纳
参考技术C 转换的含义是通过改变一个变量的类型为别的类型从而改变该变量的表示方式。为了类型转换一个简单对象为另一个对象你会使用传统的类型转换操作符。比如,为了转换一个类型为doubole的浮点数的指针到整型:
代码:
int i;
double d;
i = (int) d;或者:i = int (d);
对于具有标准定义转换的简单类型而言工作的很好。然而,这样的转换符也能不分皂白的应用于类(class)和类的指针。ANSI-C++标准定义了四个新的转换符:'reinterpret_cast', 'static_cast', 'dynamic_cast' 和 'const_cast',目的在于控制类(class)之间的类型转换。
代码:
reinterpret_cast<new_type>(expression)
dynamic_cast<new_type>(expression)
static_cast<new_type>(expression)
const_cast<new_type>(expression)
参考技术D no

c++ 之 类型转换

一、隐式类型转换

int m = 3 + 45.6; //48.6000000000 截断为48,将小数部分进行截断

二、C风格 显式类型转换(强制类型转换)

//int k = 5 % 3.2; 编译器报错

int k = 5 %(int)3.2; //C语言风格的强制类型转换,但需要程序员来保证数据正确可转
int k = 5 % int(3.2); //函数风格的强制类型转换(C语言风格的强制类型转换中的一种)
int k = 5 %(int)"dddd"; //C语言风格的强制类型转换,但结果肯定错误
//所以C语言风格的强制类型转换是一种不安全的类型强制转换

三、C++类型转换

//C++出来支持C风格的类型转换,但提供4中C++的强制类型转换,分别用于不同的目的

//目的是为了提供丰富的含义和功能,更好的类型检查机制,方便代码的书写与维护
1.static_cast
2.dynamic_cast
3.const_cast
4.reinterpret_cast

这四种强制类型转换被称为 "命名的强制类型转换"
1.static_cast:静态转换(可以理解为C风格的强制类型转换,但编译器会检查其合法性)
//通用形式

//强制类型转换名<type>(express);1.static_cast:静态转换(可以理解为C风格的强制类型转
换,但编译器会检查其合法性)
  可用于
    a.相关类型的转换(如浮点型转整型)
    int i = static_cast<int> 100.0;
b.子类转换为父类(继承关系)
c.void *指针与其他指针之间的转换(被强制转换的是void *类型指针)
  不可用于
   a.一般不能用于不同类型指针之间的转换
2.dynamic_cast:主要应用于 运行时类型识别与检查。
主要用来父类型和子类型之间的转换用(将父类型指针指向子类型对象)

3.const_cast:去除指针或引用的const属性(编译时进行类型转换)不能进行不同类型之间的转换

4.reinterpret_cast:重新解释(处理无关类型的转换)可以乱转,安全性较差
  常用于如下两种类型的转换
a.将整型转换为指针
b.将一种类型的指针转换为另一种类型的指针。
c.指针转换为整型

四、总结

1.强制类型转换均不建议使用,会抑制编译器报错

2. reinterpret_cast非常危险,const_cast使用则意味着设计缺陷

3. 如果实在需要进行强制类型转换,则要使用C++风格的强制类型转换

4. reinterpret_cast只要合乎规则的使用,则很好用

以上是关于C++中的数据类型强制转换的主要内容,如果未能解决你的问题,请参考以下文章

c++ 之 类型转换

c和c++中,对结构体进行强制类型转换!

C++ --- 强制转换运算符

c++中的类型转换

深入理解C++中五种强制类型转换的使用场景

深入理解C++中五种强制类型转换的使用场景