Effective C++ 条款27
尽量少做转型动作
尽量少做转型动作有什么目的?非常明显无非就是提高程序的稳定性。提高程序的运行效率。
那么。有哪些转型方式?每种方式都有什么弱点? 这是我们本节学习的重点。
C++有四种转型:
const_cast<T>(expression)
dynamic_cast<T>(expression)
reinterpret_cast<T>(expression)
static_cast<T>(expression)
每种转型的作用例如以下:
1.const_cast通常被用来将对象的常量特性转除(cast away the constness)。它也是唯一由此能力的C++-style转型操作符。
2.dynamic_cast主要用来运行“安全向下转型”(safe downcasting),也就是用来决定某对象是否归属继承体系中的某个类型。
它是唯一无法由旧式语法运行的动作。也是唯一可能耗费重大运行成本的转型动作(后面细讲)。
3.reinterpret_cast意图运行低级转型。实际动作(结果)可能 取决于编译器,这表明其不可移植。比如将pointer to int转为int,这类转型经常使用在低级代码。
比如。讨论讨论怎样针对原始内存(raw memory)写一个调试用的分配器(debugging allocator),见条款50.
4.static_cast运行强迫隐式转换(implicit conversions)。比如将int转为double,non-const转为constant等。
它也能够用来运行一些转换的反响转换。但无法将const转为non-const。
我来总结一下以上的四点。
首先对于const_cast是起到一个去除const特性的作用。
去掉const属性:const_case
class Window{
public:
virtual void onResize(){……};
……
};
class specialWindow:public Window{
public:
virtual void onResize(){
static_cast<Window>(*this).onResize();//调用的是副本。
……
}
};
上面代码的运行结果是基类中的数据没有变化,derived类中的数据发生变化。这是由于static_cast<Window>(*this).onResize();这句调用的是基类的副本,和当前对象无关。
作者非常强调这部分内容。但是,大家不要变傻。我们细致看一下代码,他转型的本来就是一个副本!仅仅需修改一点点就能实现一致性。
例如以下
class Window{
public:
virtual void onResize(){……};
……
};
class specialWindow:public Window{
public:
virtual void onResize(){
static_cast<Window*>(this).onResize();//ok
……
}
};
Effective C++ 条款27的更多相关文章
- Effective C++:条款27——条款
条款27:尽量少做转型动作 单一对象可能拥有一个以上的地址!
- Effective C++ -----条款27:尽量少做转型动作
如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts.如果有个设计需要转型动作,试着发展无需转型的替代设计. 如果转型是必要的,试着将它隐藏于某个函数背后.客户随后可以调用该 ...
- [More Effective C++]条款22有关返回值优化的验证结果
(这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...
- More Effective C++ 条款0,1
More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...
- MoreEffectiveC++Item35 条款27: 要求或禁止对象产生于heap中
一 要求对象产生在heap中 阻止对象产生产生在non-heap中最简单的方法是将其构造或析构函数声明在private下,用一个public的函数去调用起构造和析构函数 class UPNumber ...
- 《MORE EFFECTIVE C++》条款27 要求或者禁止对象分配在堆上
1. 要求对象分配在堆上 临时对象一般是存在于栈中的,或者是静态对象存在于常量存储区的.那么当创建一个这样的对象的时候,一般是需要隐式或显式地调用构造函数,在销毁的时候调用析构函数的.可以从这方面入手 ...
- Effective C++ 条款08:别让异常逃离析构函数
1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...
- Effective C++ -----条款28:避免返回handles指向对象内部成分
避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...
- Effective C++ -----条款21:必须返回对象时,别妄想返回其reference
绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...
随机推荐
- 02-c#基础之01-基础语法(一)
1.注释符 1)注销 2) 解释 2.C#中的3种注释符 1)单行注释// 2)多行注释/*要注释的内容*/ 3)文档注释///多用来解释类或者方法 2.VS中的快捷键
- windows svn 客户端连不上linux svn server
采坑记录:linux服务器上svn://127.0.0.1可以正常使用,windows客户端远程连接不上,说明是端口号的问题. linux正常配置了iptables开启了3690端口,连接不上. 干脆 ...
- int类型的整数转换成汉字
int类型的整数转换成汉字 一.源代码:IntegerNumberToChinese.java package cn.com.zfc.example; import java.util.Scanner ...
- 【HDU 3662】3D Convex Hull
http://acm.hdu.edu.cn/showproblem.php?pid=3662 求给定空间中的点的三维凸包上有多少个面. 用增量法,不断加入点,把新加的点能看到的面都删掉,不能看到的面与 ...
- luoguP4466 [国际集训队]和与积 莫比乌斯反演
自然想到枚举\(gcd(a, b)\),不妨设其为\(d\),并且\(a = di, b = dj(a > b)\) 那么\(\frac{ab}{a + b} = \frac{dij}{i + ...
- 【SPFA】POJ1511-Invitation Cards
[题目大意] 给出一张有向图,以1位源点,求“从源点出发到各点的距离”和“与各点返回源点的距离和”相加得到的和. [思路] 毫无疑问是最短路径,但是这数据量就算是SPFA也绝壁会超时啊,抱着必死的心态 ...
- java 中常用的类
java 中常用的类 Math Math 类,包含用于执行基本数学运算的方法 常用API 取整 l static double abs(double a) 获取double 的绝对值 l sta ...
- 2013年JavaScript开发人员调查结果
JavaScript开发人员调查现在已经结束,一如既往社区对结果进行了进一步分析: 总结(汉语) 原始数据(电子表格) 2012年结果 51%的被参与者写客户端代码,而28%的人说他们编写服务器端代码 ...
- js ajax post 提交的时候后台接收不到参数,但是代码没有错,怎么回事
这个错误有两点,你自己写的php页面里面的参数接收出错了 还有就是你没有写一句重要的代码告诉浏览器 你使用post提交方式去提交 xhr.setRequestHeader("Content- ...
- Tasker to detect application running in background
We used to be told that tasker is only capable of detecting foreground application, if the app gets ...