对指针来说,可以指定指针本身为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 例子)

最新文章

  1. arcgis对谷歌遥感影像拼接
  2. ASP.NET MVC 监控诊断、本地化和缓存
  3. 一头扎进EasyUI
  4. CodeForces - 427A (警察和罪犯 思维题)
  5. 使用gson-1.6.jar解析json
  6. Delphi通过Map文件查找内存地址出错代码所在行
  7. jquery中mouseout和mouseleave 事件的区别
  8. IOS(swift)-数据存储 &#183; 用NSUserDefaults存储配置信息
  9. js浏览器兼容
  10. Creating and using a blendspace in c++
  11. python中的基本数值计算
  12. C 编译过程浅析
  13. MySQL联结查询和组合查询
  14. go bytes缓冲区使用介绍 -转自https://www.cnblogs.com/--xiaoyao--/p/5122138.html
  15. rtpproxy 配置
  16. 七个不可错过的React组件库与开发框架
  17. 微软职位内部推荐-Senior Software Engineer - Front End
  18. 深入理解Linux网络技术内幕——Notification内核通知表链
  19. ecmascript 6 的arguments转数组的代码
  20. angular学习笔记(九)-css类和样式2

热门文章

  1. iOS 蓝牙的GameKit用法
  2. 我用的主机,推荐给大家【gegehost】【戈戈主机】
  3. vultr服务器L2TP搭建
  4. hibernate 批量抓取
  5. bash之数组
  6. 将Jar安装到本地仓库和Jar上传到私服
  7. 03C#数据类型
  8. Python应该怎样实现快速入门?
  9. 基于ant design form的二次封装
  10. pip install MySQL-python error &quot;can&#39;t open config-win.h&quot;