C++基础语言之(三C++中四种cast转换)

一、C中的隐式类型转换和显式类型转换:

说起类型转换,我们常见的就是C中的隐式类型转换和显式类型转换:

1.隐式类型转换

/* 隐式转换就是系统默认的、不需要加以声明就可以进行的转换。
 * 在隐式转换过程中,编译器无需对转换进行详细检查就能够安全地执行转换。 
 */
int i=1;
float f=i;

2.显式类型转换(强制类型转换)

/* 区别在于当向下转换时如果不显示转换就会有问题 */
float a = 4.5; 
int b = a;         // float不能自动转化为int,这里不用显式类型转换就会报错
int c = (int)a;    // 这里用显式类型转换就不会报错

隐式类型转换和显式类型转换的区别:

隐式类型转换:

优点:性能好

缺点:可读性差

显式类型转换:

优点:可读性高

缺点:性能差


二、C++中四种cast转换:

C++中的类型转换比C中的功能更强大,用途范围更广,建议使用!它共有四种cast转换。

这四种cast转换分别为:

static_cast(expression);        // 静态转换
dynamic_cast(expression);       // 动态转换
reinterpret_cast(expression);   // 重述转换
const_cast(expression);         // 常转换

1.static_cast(expression);

static_cast最常用的转换,但是转换的时候不会检查类型来保证转换的安全性,因此安全性相对其他转换较低。

static_cast本质上是传统c语言强制转换的替代品。

需要注意的是:static_cast不能转换掉expression的const、volitale、或者__unaligned属性。

class Base{ };    // 基类(父类)
class Derived : public Base{ };    // 派生类(子类)
 
void main()
{
	// 基本类型转换 float -> int
	int i;
	float f = 67.27f;
	i = static_cast(f);

	//子类 -> 父类
	Derived d;
	Base b = static_cast(d);
	
	//父类 -> 子类
	Base bb ;
//	Derived* dd = static_cast(bb);  //compile error
	Base* pB = new Base;
	Derived* pD = static_cast(pB); //编译通过,但是是不安全的(例如访问子类成员)
}

2.dynamic_cast(expression);

该运算符把expression转换成T类型的对象。

dynamic_cast转换操作符在执行类型转换时首先将检查能否成功转换,如果能成功转换则转换之,如果转换失败,如果是指针则反回一个0值,如果是转换的是引用,则抛出一个bad_cast异常,所以在使用dynamic_cast转换之间最好使用if语句对其转换成功与否进行测试。

注意:

(1)T必须是类的指针、类的引用或者void *。如果T是类指针类型,那么expression也必须是一个指针,如果T是一个引用,那么expression也必须是一个引用。

(2)dynamic_cast转换符只能用于含有虚函数的类。

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换(子类->子类/基类)时,dynamic_cast和static_cast的效果是一样的;在进行下行转换(基类->子类)时,dynamic_cast具有类型检查的功能,比static_cast更安全。

class Base
{
public:
	virtual void foo(){};
};
 
class Derived : public Base
{
 
};
 
void main()
{
	//基类 -> 子类
	Base *pb1 = new Base;
	Derived *pd1 = dynamic_cast(pb1); //失败,pd1 = NULL
 
	//子类 -> 子类
	Base *pb2 = new Derived;
	Derived *pd2 = dynamic_cast(pb2); //成功
 
	//子类 -> 基类
	Base *pb3 = new Derived;
	Base *pd3 = dynamic_cast(pb3);		 //成功
}

3. reinterpret_cast(expression);

interpret是解释的意思,reinterpret即为重新解释,此标识符的意思即为数据的二进制形式重新解释,但是不改变其值。

T必须是一个指针、引用、算术类型、函数指针或者成员指针。

该操作符用于将一种类型转换为另一种不同的类型,比如可以把一个整型转换为一个指针,或把一个指针转换为一个整型,因此使用该操作符的危险性较高,一般不应使用该操作符。

示例:

int i;
char *p = "This is a example.";
i = reinterpret_cast(p);   //将指针p的值(即地址)转为int型 【如 0x00b4cd10 -> 11848976】

4.const_cast(expression);

其中T必须为指针或引用 。

主要是用来去掉const属性,当然也可以加上const属性。主要是用前者,后者很少用。

class A
{
public:
	int num;
};
 
void main()
{
	//类指针
	const A a;
	const A* pA = &a;
	pA->num = 10;                //compile error
	A* pA2 = const_cast(pA);
	pA2->num = 11;               //success
 
	//基本数据类型
	const int i = 3;
	int* p = const_cast(&i);
	*p = 10;                     //success
 
	//加上const属性
	int j = 10;
	const int* k = const_cast(&j);//一般可以直接写const int* k = &j;
}

你可能感兴趣的:(C++)