Arce 发表于 2021-8-8 13:09:44

C++编程经验(6):使用C++风格的类型转换

为什么推荐使用C++风格类型转换?
不是说别的风格的类型转换机制不好,但是写C++代码的话,既然人家有,那就慢慢的适应嘛,入乡随俗。
我们以前写类型转换一般是这样的:(type) expression,而C++引进了四个类型转换的操作符:
static_cast
const_cast
dynamic_cast
reinterpret_cast
以前那样写,现在只不过改成这样写:static_cast(expression)
举个例子哈:
假设你想把一个 int 转换成 double,以便让包含 int 类型变量的表达式产生出浮点数值的结果。
如果用 C 风格的类型转换,你能这样写:
int a;
...
double b = (double)a;
如果用上述新的类型转换方法,你应该这样写:
double result = static_cast<double>(a);

如何驾驭C++风格的类型转换?
static_cast 就不多说了吧,前面提到了,功能呢,跟C风格的类型转换功能大体上是一样的。
不过呢,它也有功能上限制。例如,你不能用 static_cast 象用 C 风格的类型转换一样把 struct 转换成 int 类型或者把 double 类型转换成指针类型,另外,static_cast 不能从表达式中去除 const 属性,因为这是别的类型转换符(const_cast)的功能。
const_cast 用于且仅用于类型转换掉表达式的 const 或 volatileness 属性。
class father { ... };
class son: public father { ... };
void update(son* psw);
son sw;                // sw 是一个非 const 对象。
const son& csw = sw;   // csw 是 sw 的一个引用,它是一个 const 对象

update(&csw);// 错误!不能传递一个 const son* 变量给一个处理 son*类型变量的函数
update(const_cast<son*>(&csw)); // 正确,csw 的 const 被显示地转换掉
update((son*)&csw);// 同上,但用了一个更难识别的 C 风格的类型转换

father *pw = new son;
update(pw);         // 错误!pw 的类型是 father*,但是 update 函数处理的是 son*类型
update(const_cast<son*>(pw));// 错误!const_cast 仅能被用在影响 constness or volatileness 的地方上。,
                  // 不能用在向继承子类进行类型转换。
dynamic_cast,它被用于安全地沿着类的继承关系向下进行类型转换。这就是说,你能用 dynamic_cast 把指向基类的指针或引用转换成指向其派生类或其兄弟类的指针或引用,而且你能知道转换是否成功。失败的转换将返回空指针(当对指针进行类型转换时)或者抛出异常(当对引用进行类型转换时):
father* pw;
...
update(dynamic_cast<son*>(pw));// 正确,传递给 update 函数一个指针是指向变量类型为 son的 pw 的指针

void updateViaRef(son& rsw);
updateViaRef(dynamic_cast<son&>(*pw));//正确。 传递给 updateViaRef 函数 SpecialWidget pw 指针,如果 pw
这四个类型转换符中的后一个是 reinterpret_cast。emmm,好像这个转换符不是很受待见。
使用这个操作符的类型转换,其的转换结果几乎都是执行期定义。 因此,使用reinterpret_casts 的代码很难移植。
reinterpret_casts 的普通的用途就是在函数指针类型之间进行转换。
转换函数指针的代码是不可移植的(C++不保证所有的函数指针都被用一样的方法表示),在一些情况下这样的转换会产生不正确的结果,所以你应该避免转换函数指针类型,除非万不得已。



文档来源:51CTO技术博客https://blog.51cto.com/u_15197573/3310088
页: [1]
查看完整版本: C++编程经验(6):使用C++风格的类型转换