C++Primer中:任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。ps:顶层const表示指针本身是个常量;底层const表示所指对象是个常量。
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
例:
const char *m; // 底层const
string t=static_cast<string>(m);
为什么这样的操作合法,而且t是可写的,static_cast难道也去除了const属性?
来自segmentfault的解答:
首先,static_cast并不能去除const属性,只要const_cast才能改变表达式的常量属性;同样,也不能用const_cast改变表达式的类型。
static_cast<T>(x)的语义差不多是这样的: 以x为参数构造一个T类型的返回值,这个转型的过程必需是在编译期可以确定的。
如果有const
int x=10:x包含顶层const,而不是底层const
static_cast<int>(x)是正确的,因为你可以从一个const
int构造一个int。个人认为:这种情况下,构造一个int,是一种copy操作,也就是赋值运算,而在进行赋值运算时,顶层const不受影响,但底层const的要求:必须要有相同的底层const资格,或者允许转换(一般非常量可以转换为常量)见C++Primer
58页。
static_cast<int
&>是不正确的,因为你不能从const
int获得一个int
&,此时必需用const_cast。
个人认为:这种情况下,构造一个int,是一种copy操作,也就是赋值运算。因为int &是一个(普通)引用,它不能绑定到常量上,要想绑定到常量上,必须使用const int &。
static_cast<const int &>正确的,因为你可以依据const int获得一个const int &
在例子中,的确可以从const char *正常构造一个std::string,因为std::string有这么一个构造函数。但是你不能从const char *构造一个int,只能得到一个const int。这里用到构造函数string (const char* s);来生成string实例, 即是向编译器保证 不会去更改char* m指向的内存. 实际上, 这里string重新开辟了一段内存, 把char* m的内容进行了拷贝. 所以更改string实例不会更改char* m的内容.
所以关键还是在 构造一词上。