在C++的程序设计里面尽量少做一些转型动作
1.C++一共提供了4中新式的转型
*const_cast<type>(expression)
dynamic_cast<type>(expression)
reinterpret_cast<type>(expression)
static_cast<T>(expression)*
下面将一一分别介绍:
(1)const_cast(expression)。通常被用来将对象的常量性移除,只能改变运算对象的底层const。
const char *pc //这是一个底层const
char *p = const_cast<char*>(pc)//正确,但是通过p写值是无定义的行为。
将常量对象转化为非常量对象的行为,我们称为“去掉const的性质(cast away the const)”。一旦我们去掉了某个对象的const性质,编译器就不再阻止我们对对象进行写操作了。如果对象本身不是一个常量,使用常量类型转换获得写权限的行为是合法的。然而,如果对象是一个常量通过const_cast(expression)执行写操作会产生无法定义的后果。只有const_cast能够改变表达式的常量属性。它常常用在有重载操作的上下中。
(2)dynamic_cast(expression)。主要用来执行“安全向下转型”,也就用来决定某对象是否归属继承体系的某个类。当我们将这个运算符运用在某种类型的指针或者引用上,并且该类型含有虚函数时,运算符将使用指针或引用绑定的对象的动态类型。所以它主要适用于一下的情况:我们想使用基类对象的指针或引用来调用某个派生类的操作,并且该操作不是虚函数。
如果一个dynamic_cast(expression)是指针的类型失败了,它将返回一个0,如果转型目标是引用失败了它将返回一个bad_cast异常。
class Base
{
public :
virtual void foo() const
{
cout << "Base class" << endl;
}
};
class Derived :public Base
{
public :
virtual void foo() const
{
cout << "Derived class" << endl;
}
void func() const
{
cout << "hello world!" << endl;
}
};
int main()
{
Base *Pb = new Derived;
Derived* Pd = dynamic_cast<Derived*>(Pb);
Pd->func(); //将输出hello world!
return 0;
}
(3)reinterpret_cast(expression)。意图执行低级别的转型,实际的转型动作可能取决于编译器,这也表示它不可以移植。通常为运算符对象的位模式(二进制模式)提供较低层次上的重新解释。下面举两例子:
例子1:
int i;
char *p="This is a one";
i = reinterpret_cast<int>(p);
/*
此时i和p的值完全相同,reinterpret_cast的作用是将p的值以二进制
的形式解释为int型并且赋值给i
*/
例子2:
int *ip;
char *pc = reinterpret_cast<char*>(ip);
//我们必须牢记pc所指的真实对象是一个int而非字符,如果把它当作普通字符
//就可能在运行时发生错误。
string s(pc); //可能会导致异常的行为。
(5)static_cast(expression)。任何具有明确定义的类型转换,只要不包含底层的const,都可以使用static_cast。
例如: 把一个较大的算术类型赋值给一个较小的类型时。
将一个non-const类型转化为const类型
将void*转化为type类型。