欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++强制类型转换

程序员文章站 2022-08-09 12:50:29
static_cast 任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。例如: int i = 3, j = 2; double slope = static_cast(i) / j; static_cast还可以用于把void*转换成别的类型 ......
static_cast
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。例如:
int i = 3, j = 2;
double slope = static_cast<double>(i) / j;
 
static_cast还可以用于把void*转换成别的类型的指针:
void* p = &slope;
double *dp = static_cast<double*>(p);
 
可以认为static_cast和C中的强制类型转换类似,例如,用C中的强制类型转换是这样的:
double slope = ((double)i) / j;
 
static_cast还可以用于处理explicit构造函数。例如:
class A
{
public:
explicit A(int n):n(n){}
 
int getN(){return n;}
private:
int n;
};
 
int getN(A a)
{
return a.getN();
}
 
这种情况下,写
getN(12);
是不合法的。可以这么写:
getN(static_cast<A>(12));
 
const_cast
只能用于改变底层const。例如,将常量对象转换成非常量对象(cast away the const)。例如:
const char *pc;
char *p = const_cast<char*>(pc);
当然,如果pc所指向的对象本来就是一个常量,上述代码也可以通过编译,但是执行结果是未定义行为。
 
注意:只有const_cast能改变表达式的常量属性,用别的方式改变表达式的常量属性会引发编译错误。
 
const_cast常用在函数重载中:
例如,有一个函数,接受const类型的引用作为参数,返回一个const类型的引用:
const string &shorter(const string &s1, const string &s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
如果我们把两个非常量的string类型的变量作为实参传给这个函数,那么返回值依然是const string &。所以我们需要重载这个函数,当它的实参不是常量时,返回一个非常量的引用:
string &shorter(string &s1, string &s2)
{
return s1.size() <= s2.size() ? s1 : s2;
}
这样写就解决了问题。但是,为了避免两个重载函数的函数体中的重复代码,可以把第二个函数改成:
string &shorter(string &s1, string &s2)
{
auto &r = shorter(const_cast<const string&>(s1), const_cast<const string&>(s2));
return const_cast<string&>(r);
}
注意:1、函数体的第一行将实参强制转换成对const的引用,所以,第一行中shorter的返回值r是绑定在string&上的。因此函数体的第二行将r强制转换成string&是安全的;2、要用non-const版本的函数去调用const版本的函数,千万不要反过来。
 
reinterpret_cast
在内存位的层次上进行转换,用于各种胡来。例如:
char *p;
int n = reinterpret_cast<int>(p);
 
dynamic_cast
用于在一个派生体系中进行动态类型转换。一般是将指向基类的指针(或引用)转换为指向派生类的指针(或引用)
当转换失败时(即,被转换的指针(或引用)并不是指向派生类的指针(或引用)):
1、转换对象是指针:返回一个值为0的指针
2、转换对象是引用:抛出异常std::bad_cast,这个异常定义在typeinfo标准库头文件中。
注意:dynamic_cast,在多数编译器上,都比其它类型转换要慢。
 
补充说明:
把非const变量转成const,可以使用static_cast,把const转成非const,只能使用const_cast。
 
在重载中使用const_cast是合理的。除此之外的强制类型转换(static_cast和dynamic_cast)都要慎用。reinterpret_cast尤其是用于扯淡的。