条款3:尽可能地使用const

如下为const修饰的几种类型:

char name[] = "benxintuzi";

char* p1 = name;                // non-const pointer, non-const data

const char* p2 = name;         // non-const pointer, const data

char* const p3 = name;         // const pointer,      non-const data

const char* const p4 = name;  // const pointer,      const data

小技巧:

如果const出现在*号左边,就是non-const pointer, const data;如果出现在*号右边,就是const pointer, non-const data。

const的另外一个用途就是修饰函数:const可以修饰返回值、参数、函数本身。

现在定义一个类TextBlock操作一个字符串的某个字符:

 1 #include<iostream>
 2
 3 using namespace std;
 4
 5 class TextBlock
 6 {
 7 public:
 8     TextBlock(string text)
 9     {
10         this->text = text;
11     }
12     const char& operator[](size_t position) const   // 操作常量对象
13     {
14         return text[position];
15     }
16     char& operator[](size_t position)               // 操作非常量对象
17     {
18         return text[position];
19     }
20
21 private:
22     string text;
23 };
24
25
26 int main()
27 {
28     TextBlock name("benxintuzi");
29     cout << name[0];                    // 调用non-const类型的operator[]
30     name[0] = ‘B‘;                      // 正确
31     const TextBlock cname("tuzi");
32     cout << cname[0];                   // 调用const类型的operator[]
33     cname[0] = ‘T‘;                     // 错误
34
35     return 0;
36 }

注意:

上边的重载[]操作符返回的是char&,而不是char,否则name[0] = ‘B‘这样的语句就不能通过编译。究其原因就是如果返回一个内置类型,那么改变其值是不好的,因此C++不会同样这样做,即使有些编译器可以通过,那么最终你改变的也只是一个副本而已,原始的字符并没有改变(因为如果不返回引用,只是返回类型本身的话,C++会调用复制构造函数返回一个副本而已)。

如果我们可以确定成员函数不会改变对象的任何变量,那么我们就可以将函数声明为const,就是:

 1 #include<iostream>
 2
 3 using namespace std;
 4
 5 class TextBlock
 6 {
 7 public:
 8     size_t stat() const;
 9
10 private:
11     int length;
12     bool use;
13 };
14 size_t TextBlock::stat() const    // const函数表示不会改变对象中的所有变量
15 {
16     use = true;
17     length = 10;
18     return length;
19 }
20
21 int main()
22 {
23     TextBlock tb;
24     cout << tb.stat() << endl;    // assignment of member ‘TextBlock::use’ in read-only object ...
25     return 0;
26 }

但若是我们想在const函数中改变某个特殊成员变量怎么办呢?利用mutable对变量进行修饰即可:

1 class TextBlock
2 {
3 public:
4     size_t stat() const;        // const函数表示不会改变对象中的所有变量
5
6 private:
7     mutable int length;
8     mutable bool use;
9 };
时间: 2024-11-10 07:34:27

条款3:尽可能地使用const的相关文章

Effective C++ 条款3 尽可能用const

1. const可被施加于任何作用域内的对象,函数参数,函数返回类型,成员函数本体.用const修饰指针,如果const出现在*之前,表明指针不能更改所指向的对象的内容,如果const出现在*之后,表明指针只能指向同一块内存.另外int const*p和const int*p含义相同.如果对象成员有普通指针,那么构造该类的一个const对象时,const修饰使得该指针只能指向同一块内存,但指针指向的内容可以改变. 2. 将某些东西声明为const可以帮助编译器侦测出错误用法. 3. 编译器强制实

条款21: 尽可能使用const

对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const,还有,两者都不指定为const: char *p = "hello"; // 非const指针, // 非const数据 const char *p = "hello"; // 非const指针, // const数据 char * const p = "hello"; // const指针, // 非const数据 const char

Effective C++ 条款三 尽可能使用const

参考资料:http://blog.csdn.net/bizhu12/article/details/6672723      const的常用用法小结 1.用于定义常量变量,这样这个变量在后面就不可以再被修改     const int val = 90;      val = 100;   错误 2. 保护传参时参数不被修改,如果使用引用传递参数或按地址传递参数给一个函数,在这个函数里这个参数的值若被修改, 则函数外部传进来的变量的值也发生改变,若想保护传进来的变量不被修改,可以使用const

条款32: 尽可能地推迟变量的定义

// 此函数太早定义了变量"encrypted" string encryptPassword(const string& password) { string encrypted;//默认构造函数初始化 if (password.length() < MINIMUM_PASSWORD_LENGTH) { throw logic_error("Password is too short"); } 进行必要的操作,将口令的加密版本 放进encrypted

条款3:尽可能的使用const

const成员函数的一般好处有: 它使得class接口比较容易理解. 它使得操纵const对象成为可能. 使用的过程中应该在const与non const成员函数之间避免代码重复: class TextBlock { public: ... const char & operator[](std::size_t position)const { ... //边界检查 ... //日志数据访问 ... //校验数据完整性 return text[position]; } char & ope

Effective C++ -----条款03:尽可能使用const

如果关键字const出现在星号左边,表示被指物是常量:如果出现在星号右边,表示指针自身是常量:如果出现在星号两边,表示被指物和指针两者都是常量. char greeting[] = " hello"; char* p = greeting;  //non-const pointer,non-const data const char* p = greeting;  //non-const pointer,const data  声明p为一个指向常量的greeting的指针,p指向的对象

条款2:尽量以const enum inline 来替换 #define

这里说的意思其实相当于,宁可以用编译器来替换预处理器 因为使用预处理器可能使得被处理过的东西无法进入符号表,例如 #define MAXLEN 16 这里的MAXLEN并没有进入符号表,这样有编译错误出现的时候,提示的都是16而并不是MAXLEN,这样就会带来很多的错误. 对于上面的那个式子,可以尝试的使用用一个常量去替换上面的宏:const int MAXLEN = 16 注意,常量的定义式往往被放在头文件中 应该要注意到的一点:class专属常量,为了将作用域限制在一个class内,应该让他

条款1:尽量用const和inline而不用#define [effective C++ 学习笔记]

这一节主要讲得是,为什么const,inline要比#define好,总结起来如下: 1 如果使用#define,编译器只是会傻乎乎的将define后面的内容替换成定义的变量,拿 const double ASPECT_RATIO = 1.653;举例,如果这样定义后,代码中使用 ASPECT_RATIO 时,在编译代码的时候,会将 ASPECT_RATIO 变量统一替换成1.653这个数字. 看似这样做没什么问题,但是会带来可能的隐患. 隐患一:报错的时候,提示错误的原因会是1.653,这样不

条款02:尽量以const,enum,inline替换#define

1.内置类型用const替换#include 2.字符串类型用const的两种方式 3.数组的大小最好用enum这样给出 4.宏表达式#define CALL_WITHMAX(a,b) f((a)>(b))?(a):(b))可以替换为某个inline函数: 注意: