对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const,还有,两者都不指定为const:

char *p              = "hello";          // 非const指针,
// 非const数据 const char *p = "hello"; // 非const指针,
// const数据 char * const p = "hello"; // const指针,
// 非const数据 const char * const p = "hello"; // const指针,
// const数据

声明迭代器为const表示这个迭代器不得指向不同的东西,但它所指的东西的值是可以改变的,如果希望迭代器所指的东西不可被改动,可以使用const_iterator

vector<int>vec = { ,, };
const vector<int>::iterator iter = vec.begin();
*iter = ;//ok
iter++;//出错
vector<int>::const_iterator it = vec.begin();
*it = ;//出错
++it;//ok

const的一些强大的功能基于它在函数声明中的应用。在一个函数声明中,const可以指的是函数的返回值,或某个参数;对于成员函数,还可以指的是整个函数。


类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。

在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于改变数据成员的成员函数不能加 const。所以 const 关键字对成员函数的行为作了更加明确的限定:有 const 修饰的成员函数(指 const 放在函数参数表的后面,而不是在函数前面或者参数表内),只能读取数据成员,不能改变数据成员;没有 const 修饰的成员函数,对数据成员则是可读可写的。

除此之外,在类的成员函数后面加 const 还有什么好处呢?那就是常量(即 const)对象可以调用 const 成员函数,而不能调用非const修饰的函数。非常量对象可以随意调用const或非const修饰的函数。正如非const类型的数据可以给const类型的变量赋值一样,反之则不成立。const 引用的是对象时只能访问该对象的const 函数

class student
{
public:
student(){}
student(const string &nm, int sc = )
:name(nm), score(sc){}
void set_student(const string &nm, int sc = )
{
name = nm;
score = sc;
}
const string &get_name()const
{
return name;
}
int get_score()const
{
return score;
} private:
string name;
int score;
}; void output(const student &stu)
{
//正常调用
cout << stu.get_name();
cout << stu.get_score();
}

若get_name和get_score没有const修饰,则const student变量不能调用这两个函数

class student
{
public:
student(){}
student(const string &nm, int sc = )
:name(nm), score(sc){}
void set_student(const string &nm, int sc = )
{
name = nm;
score = sc;
}
const string &get_name()
{
return name;
}
int get_score()
{
return score;
} private:
string name;
int score;
}; void output(const student &stu)
{
//编译出错
cout << stu.get_name();
cout << stu.get_score();
}

为什么 get_name() 前面也加 const。如果没有前后两个 const 的话,get_name() 返回的是对私有数据成员 name 的引用,所以通过这个引用可以改变私有成员 name 的值(不会报错),如

student stu("wang", );
stu.get_name() = "li";

令函数返回一个常量值,往往可以降低因客户错误而造成的意外

/*
返回const对象是为了避免出现以下这种错误
Rational a,b,c;
(a * b) = c;
若a、b、c是内置类型,直接出错,而一个良好的用户自定义类型的特征是避免无端地与内置类型不兼容
*/
class Rational{};
const Rational operator* (const Rational &lhs, const Rational &rhs);

-----------------------------------------------------------------------------------------------------------------------------------------------------

//length为const成员函数,不能修改成员变量,所以用mutable关键字修饰,这样即使在const成员函数内也可能会被改变
//被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。
class CTextBlock
{
public:
size_t length() const;
private:
char* pText;
mutable size_t textLength;
}; size_t CTextBlock::length() const
{
textLength = strlen(pText);
return textLength;
}

两个成员函数如果只是常量性不同,可以被重载(指该函数是否为const成员函数)

class TextBlock
{
public:
TextBlock(char *str):text(str){}
const char& operator[](size_t position) const
{
return text[position];
}
char& operator[](size_t position)
{
return text[position];
}
private:
string text;
}; int main()
{
//调用non-const TextBlock::operator[]
TextBlock tb("Hello");
cout << tb[] << endl; //调用const TextBlock::operator[]
const TextBlock ctb("World");
cout << ctb[]; system("pause");
return ;
}

当const和non-const成员函数有着实质等价的实现时,令non-const版本调用const版本可避免代码重复(effective c++ p24 例子)

条款21: 尽可能使用const的更多相关文章

  1. Effective C++_笔记_条款03_尽可能使用const

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 关键字const多才多艺,语法变化多端.关于const的基本用法 ...

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

    如果关键字const出现在星号左边,表示被指物是常量:如果出现在星号右边,表示指针自身是常量:如果出现在星号两边,表示被指物和指针两者都是常量. char greeting[] = " he ...

  3. 《Effective C++》读书笔记 条款03 尽可能使用const 使代码更加健壮

    如果你对const足够了解,只需记住以下结论即可: 将某些东西声明为const可帮助编译器侦测出错误用法,const可被施加于任何作用于内的对象.函数参数.函数返回类型.成员函数本体. 编译器强制实施 ...

  4. 条款03 尽可能使用const

    一.概述 使用const约束对象:可以获得编译器的帮助(指出相关出错的地方) const与成员函数:const重载.转型.避免代码重复 二.细节 1. 为什么有些函数要返回const对象(看上去没必要 ...

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

    参考资料:http://blog.csdn.net/bizhu12/article/details/6672723      const的常用用法小结 1.用于定义常量变量,这样这个变量在后面就不可以 ...

  6. Effective C++ 之 Item 3:尽可能使用 const

    Effective C++ Chapter 1. 让自己习惯C++(Accustoming Yourself to C++) Item 3. 尽可能使用 const (Use const whenev ...

  7. 条款03:尽可能使用const

    目录 1. 总结 2. const对象 3. const函数返回值和函数参数 4. const成员函数 const成员函数的重要性 bitwise constness logical constnes ...

  8. 读书笔记_Effective_C++_条款三:尽可能使用const

    const是常量的意思,它可以定义一个不可改变的量,主要用于以下几个地方: 1. 修饰变量,使之不可改变 举个例子: const int var = 3; 此时var的值就不能改变了.也正是因为con ...

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

    场景一 用于修饰指针 char greeting[] = "Hello"; char* p = greeting; // non-const pointer, non-const ...

随机推荐

  1. raw cannot be resolved or is not a field解决办法

    解决raw文件夹问题 查看左侧项目/res文件夹下是否有raw文件夹,(一定是放到res文件夹下,raw在项目开始创建时候不会自动创建,所以要自己创建)

  2. 【Gambit】Gambit使用教程

    第一章 Gambit使用 Gambit介绍 网格的划分使用Gambit软件,首先要启动Gambit,在Dos下输入Gambit <filemane>,文件名如果已经存在,要加上参数-old ...

  3. Python_高阶函数、装饰器(decorator)

    一.变量: Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来. 对变量赋值x = y是把变量 ...

  4. Zend Studio 服务器根目录设置

    在 Apache 服务器根目录里查找 \conf\httpd.conf 例如:C:\AppServ\Apache24\conf\httpd.conf 打开后查找 DocumentRoot 标记 修改调 ...

  5. C#委托与事件的关系(转载)

    1.C#中的事件和委托的作用?事件代表一个组件能够被关注的一种信号,比如你的大肠会向你发出想拉屎的信号,你就可以接收到上厕所.委托是可以把一个过程封装成变量进行传递并且执行的对象,比如你上蹲坑和上坐马 ...

  6. 00C#

    C# C#(读作“See Sharp”)是一种简单.现代.面向对象且类型安全的编程语言.C# 起源于 C 语言家族,因此,对于 C.C++ 和 Java 程序员,可以很快熟悉这种新的语言.C# 已经分 ...

  7. 递归删除N天前的文件夹及子文件夹下的特定文件

    @echo offrem 设置被删除文件夹路径set SrcDir=D:\tmp\test\rem 设置文件保存天数set Days=2rem /p指定搜索文件的路径 /s 在子目录中搜索 /m 指定 ...

  8. jquery 应用

    http://www.jq22.com/ gwj6396668@163.com

  9. 借助百度地图API制作企业百度地图

    做网站需要插入地图,可以借助百度地图API,具体步骤如下: 1.打开百度地图API的网址:   http://api.map.baidu.com/lbsapi/creatmap/ 2.设置中心点 3. ...

  10. 笔试算法题(54):快速排序实现之单向扫描、双向扫描(single-direction scanning, bidirectional scanning of Quick Sort)

    议题:快速排序实现之一(单向遍历) 分析: 算法原理:主要由两部分组成,一部分是递归部分QuickSort,它将调用partition进行划分,并取得划分元素P,然后分别对P之前的部分和P 之后的部分 ...