【03】尽可能使用const
1、为什么搞出const关键字?
const指定一个语义约束,指定一个对象不可修改。如果一个对象不可修改,就应该说出来。
2、const与指针
const可以修饰指向之物,也可以修改指针本身。STL中的迭代器是对指针的封装,因此,迭代器也有两个概念:指向常量对象的迭代器和常量迭代器。
vector<int>::const_iterator; //指向常量的迭代器
const vector<int>::iterator; // 常量迭代器
3、const可以与方法产生关联,可以用在方法前,方法中(形参表中),方法后。首先考虑,用在方法前,表示返回值是常量。为什么要返回const对象呢?
我们知道,方法返回值是一个临时对象,只有类型,没有名称,这个临时对象是方法内局部对象的副本。如果返回不是一个常量,客户端就能实现下面的暴行:
Rational a,b,c;
(a*b)=c; //对方法返回值进行赋值。
对于内置类型,这样的赋值行为是错误的。对于自定义类型,也应该报错。有一个准则要遵守:自定义类型应该和内置类型在行为上保持一致,除非有特殊情况。因此,为了避免客户端对方法返回值进行赋值,请返回一个const对象。
4、const在方法中,也就是出现在形参表中,这种情况很好理解,表示形参不可修改。需要注意的是:形参表不同,可以构成过载。如果形参表相同,只是常量性不同,能否构成过载?能不能构成过载的关键是:编译器能不能根据实参确定调用哪个方法,也就是过载方法的匹配程度不一样。
如果形参是引用或者指针,可以构成过载,这种情况下,形参是实参的别名,根据实参的常量性,可以确定调用哪个方法。
如果形参不是引用或者指针,不能构成过载,这种情况下,形参是实参的副本,与实参没有了关系,他们和实参的匹配程度是一样的。
5、const在方法后,表示常量方法,应该尽量使用常量方法。有两个好处:a、接口容易理解,明确表示不会修改对象内容;b、使得const对象可以调用。
考虑,我们知道non-const对象可以调用const成员方法,但是,const对象不能调用non-const成员方法,因为non-const成员方法可能会修改对象。为了让const对象调用non-const成员方法,有两种办法:一是使用const_cast<T&>或者const_cast<T*>去除对象的常量性,二是如果不修改对象,使用const成员方法,显然第二种办法更好。
6、根据成员方法的常量性,可以过载。为什么?我们知道成员方法有个隐式的常量this指针(不能指向其他对象),const成员方法限制了this指针指向const。因此,编译器可以根据方法拥有者的常量性,决定哪个方法更匹配。
7、如果返回对象的内部数据,const成员方法应该返回const引用,防止外部修改,non-const成员方法应该返回non-const引用。这里特别注意一点,内置类型的临时对象是不可修改的(exception的临时对象是可以修改的),也就是说,内置类型的临时对象不能赋值给non-const引用,考虑一下为什么?
方法返回对象的内部数据,返回值不是引用,而是内部数据的副本。第一个理由上面讲了,防止客户端对返回值赋值,第二个理由是,如果返回值不是const,就可以赋值给non-const引用,程序员用这个引用期望修改对象内部数据,是办不到的,这个时候修改的是临时对象,这往往不是程序员所期望的。
8、返回对象的内部数据,const成员方法为什么返回const引用?
我们知道,const成员方法的语义是说,不修改对象。但是由于暴露了内部数据,自己承诺不修改,但是由于自己的原因,暴露了内部数据,导致外部可以间接修改对象(我不杀伯仁,奈何伯仁因我而死)。为了避免这种情况,返回const引用,限制外部也不能修改。
9、在有些极端情况下,const成员方法也要修改对象的一部分内部数据,但是我又不想把它设计成non-const成员方法,因为non-const成员方法可以修改对象内的任意数据。这种情况下,可以使用mutable修饰字段,明确表示这些字段可以在const成员方法中修改。
10、对于过载的const成员方法和non-const成员方法,做的事情一样,只不过一个返回const引用,一个返回non-const引用,如何避免代码重复呢?
就是让一个方法调用另一个方法,让non-const成员方法调用const成员方法,这里要做两个强制转化,首先使用static_static<const T *>,把常量this指针转化为指向常量对象的常量this指针,然后使用const_cast<T&>,去除返回值的常量性。
注意:不能反向调用,也就是说,不能使用const成员方法调用non-const成员方法,因为后者可能修改对象内容。
【03】尽可能使用const的更多相关文章
- Effective C++ -----条款03:尽可能使用const
如果关键字const出现在星号左边,表示被指物是常量:如果出现在星号右边,表示指针自身是常量:如果出现在星号两边,表示被指物和指针两者都是常量. char greeting[] = " he ...
- 《Effective C++》读书笔记 条款03 尽可能使用const 使代码更加健壮
如果你对const足够了解,只需记住以下结论即可: 将某些东西声明为const可帮助编译器侦测出错误用法,const可被施加于任何作用于内的对象.函数参数.函数返回类型.成员函数本体. 编译器强制实施 ...
- 条款03 尽可能使用const
一.概述 使用const约束对象:可以获得编译器的帮助(指出相关出错的地方) const与成员函数:const重载.转型.避免代码重复 二.细节 1. 为什么有些函数要返回const对象(看上去没必要 ...
- Effective C++ 之 Item 3:尽可能使用 const
Effective C++ Chapter 1. 让自己习惯C++(Accustoming Yourself to C++) Item 3. 尽可能使用 const (Use const whenev ...
- Effective C++ 条款03:尽可能使用const
场景一 用于修饰指针 char greeting[] = "Hello"; char* p = greeting; // non-const pointer, non-const ...
- 条款03:尽可能使用const
目录 1. 总结 2. const对象 3. const函数返回值和函数参数 4. const成员函数 const成员函数的重要性 bitwise constness logical constnes ...
- C++ const用法 尽可能使用const [转载]
C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的.如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助. 1.c ...
- 尽可能使用 const
前言 const 关键字是常量修辞符,如果要告知编译器某个变量在程序中不会发生改变,则可将其声明为 const. 但,对 const 关键字的认识不能仅仅停留在这一层 - 它提供了很多更强大的功能. ...
- C++ const用法 尽可能使用const
C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的.如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助. 1.c ...
随机推荐
- TC SRM 607 DIV2
求拼接完成后的字符串包含的子回文串的数目,一开始还用暴力去做,想都不用想 肯定超时了. 复习了一下求最长子回文串的算法,发现可以类似解决. 给相邻字符之间添加一个'@'字符,这样所有的回文串都是奇数长 ...
- scrollView的几个属性contentSize contentOffset contentInset
01- ontentSize是scrollview可以滚动的区域 比如frame = (0 ,0 ,320 ,480) contentSize = (320 ,960), 代表你的scrollvie ...
- I2S和PCM
http://blog.csdn.net/azloong/article/details/6536855
- SPRING IN ACTION 第4版笔记-第三章ADVANCING WIRING-009-用SPEL给bean运行时注入依赖值
1.When injecting properties and constructor arguments on beans that are created via component-scanni ...
- 解读分库分表中间件Sharding-JDBC
[编者按]数据库分库分表从互联网时代开启至今,一直是热门话题.在NoSQL横行的今天,关系型数据库凭借其稳定.查询灵活.兼容等特性,仍被大多数公司作为首选数据库.因此,合理采用分库分表技术应对海量数据 ...
- Android 图片处理方法
//压缩图片大小 public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArr ...
- 通过Hibernate将数据库在myeclipse中逆向生成
1.首先准备好数据库. 2.在MyEclipse的右上角切换透视图,切换到MyEclipse Database Explorer 3.在最左边点击右键,选择New(也就是新建一个数据库连接),然后编写 ...
- XBMC 最新版本错误
1. Syntax error: "(" unexpected 修改 tools/depends下的makefile.include 将NDK_VER=0x9d
- MVC Action 返回类型[转]
一. ASP.NET MVC 1.0 Result 几何? Action的返回值类型到底有几个?咱们来数数看. ASP.NET MVC 1.0 目前一共提供了以下十几种Action返回 ...
- Paxos算法(转)
Paxos算法的难理解与算法的知名度一样令人敬仰,从我个人的经历而言,难理解的原因并不是该算法高深到大家智商不够,而在于Lamport在表达该算法时过于晦涩且缺乏一个完整的应用场景.如果大师能换种思路 ...