Effective C++笔记(2)—使用const
来源:互联网 发布:淘宝订单贷款能用多久 编辑:程序博客网 时间:2024/06/02 18:14
1.尽可能使用const
const的用法一直让人头疼,加上指针或引用就更头疼了,以前特意学习过一次【C++const限定符】,可能那个时候还不够深刻,这次借看书再次学习一蛤。
1.1const修饰指针的形式
先看书中的一个例子:
char greeting[]="Hello";char *p=greeting;//non-const pointer,non-const dataconst char* p = greeting;//non-const pointer,const datachar *const p = greeting;//const pointer,non-const dataconst char * const p = greeting;//const pointer,const data
上面的注释会有些迷惑,在这之前,我们清楚的知道,const可以从两个层面去限定:指针本身和指针所指向的内容。因为指针本身只是一个栈上变量而已,他存放的所指对象的地址。
然后就是关于const对指针及其所指向对象的修饰了。
Bjarne在他的The C++ Programming Language里面给出过一个助记的方法:
把一个声明从右向左读( * 读成 pointer to )。
char * const cp; //cp is a const pointer to char //即常量指针(指针本身const)const char * p; //p is a pointer to const char; //指向常量的指针(指针所指向的对象const)
在EffectiveC++中,则给出这样一个论断:
如果关键字const出现在星号的左边,则被指物为常量;
如果出现在星号右边,表示自身是常量;
如果出现在星号两边,表示被指物和指针都是常量。
也因为这个论断,我们就清楚了其实下面两条语句其实是同一个东西:
const Widget *pw;Widget const *pw;//都是指向常量的指针
1.2char指针和char数组的区别
现在就清楚多了,不过还需要清楚一个区别:
char * greeting="Hello";char greeting[]="Hello";
首先,“Hello”字符串是存放在字符常量区,在内存中是只读的。 char * greeting="Hello";
表示栈中变量greeting
存放字符常量区“Hello”的地址,但是由于“Hello”是只读的,于是*greeting='s';
这样的语句虽然没有error,但是运行时是有问题的。
而对于char greeting[]="Hello";
来说,会拷贝一份“Hello”到栈中,因此*greeting='s';
去修改其值是没有问题的。参见:StackOverFlow的回答。
这也就解释了char * greeting="Hello";
没有const限定符修饰,我们可以去修改其对象,但这种修改行为是非法的会带来不可预见的错误。
1.3const迭代器
在STL源码剖析中对迭代器的解释很详细,STL迭代器根据指针的特性塑模出来,其作用就像一个T*指针,而将迭代器加上const限定符,就类似声明一个T * const
一样(即常量指针),而当我们需要一个不可修改对象内容的迭代器时,使用const_iterator
,如下:
vector<int> vec;const vector<int>::iterator it=vec.begin();*it=10;//ok,改变所指对象内容++it;//error,类似常量指针/*******************************/vector<int>::const_iterator cit=vec.begin();*cit=10;//error,不能改变所指内容cit++;//ok,改变所指对象。
1.4const成员函数
在const成员函数中仔细学习过一波,对书中所说内容就不觉得陌生。
许多人漠视一个事实:两个成员函数如果只有常量性(constness)不同,可以被重载。
这里就不再赘述其原理,记住成员函数的默认this参数即可,在EffectiveC++
书中也说,用操作符重载的方式举例也太过造作,举一个简单的例子:
class Test{private: int a;public: Test(int x) :a(x){} void print() const{ cout << "const called" << endl; cout << "a=" << a << endl; } void print(){ cout << "non const called" << endl; cout << "a=" << a << endl; }};int main(int argc, char**argv){ Test t(2); const Test ct(1); t.print();//non-const called ct.print();//const called system("pause"); return 0;}
1.5mutable关键字
这里书中提到的两个流派:physical constness
和logical constness
与成员函数修改成员变量的“力度”有关,前者认为,当成员函数只有在不更改对象的任何成员变量时才可以说成const,而成员变量中确实有一些变量需要修改怎么办,即使在const成员函数内?此时就需要用到mutable
关键字。某些成员变量是需要有mutable特性的,比如在muduo源码中,需要在一些const成员函数中使用Mutex加锁:参见muduo 06 互斥锁和条件变量的封装
1.6casting转型
过段时间会专门花一点时间了解一蛤const_cast
、static_cast
和dynamic_cast
这几兄弟,这里简单的理解就是:
const_cast去掉const限定;
static_cast类型转换
说到转型跟const的联系,也就是作者认为,如果一个成员函数既有const的版本又有non-const版本,那么两份代码重复冗余了,因为他们干得活都是一样,为了使用const版本的成员函数来写non-const版本的成员函数,用到上述两种转型:
class TextBlock{public: const char & operator[](size_t position ) const { //.. //.. //.. return text[position]; } char & operator[](size_t position ) { //static_cast为*this加上const //const_cast为op[]的返回值移除const return const_cast<char&>( static_cast<const TextBlock&>(*this) [position] ); }};
- Effective C++笔记(2)—使用const
- Effective C++——尽可能使用const
- 《Effective C++》学习笔记条款03 尽可能使用const
- 【Effective C++】const的使用
- Effective C++——》条款3:尽可能使用const .
- 《Effective C++》读后总结(三)尽量使用const
- effective c++:条款21: 尽可能使用const
- 《Effective C++》读书笔记之const高效使用
- 【Effective C++】条款03-尽可能使用const
- Effective C++:条款03:尽可能使用const
- [Effective C++]条款03:尽可能使用const
- Effective C++--条款03:尽可能使用const
- Effective C++,Rule 3,使用const
- Effective C++学习笔记:尽可能使用const
- Effective c++笔记:03 尽可能使用const
- Prefer readonly to const - Effective C#学习笔记(2)
- const学习后记(effective C++)
- const相关用法(Effective C++_3)
- 初学C语言:
- CodeForces 367E Working routine 十字链表
- java中集合框架的基本概念整理
- 计算机的数字计算
- 欢迎使用CSDN-markdown编辑器
- Effective C++笔记(2)—使用const
- mac Finder 快捷键
- IIS中 SSL服务器证书配置以及私钥找回小结
- 个人项目-过滤代码工程文件注释
- 基于sublime搭建python开发环境(windows)
- [知了开发]“知了”优化 - WebMagic 调优
- 最详细的SVN安装使用手册-Centos6.4系统运行通过
- KCon黑客大会十大神器webzmap的安装与使用
- poj1979【基础bfs/dfs】