C++强制类型转换
程序员文章站
2022-05-03 14:22:16
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尤其是用于扯淡的。
上一篇: 丑的先讲
下一篇: ssh框架整合笔记---配置文件