对指针来说,可以指定指针本身为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. mysql提升效率

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  2. [Windows Server 2008] 404错误设置方法

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:如何设置4 ...

  3. python与shell通过微信企业号发送消息

    python与shell通过微信企业号发送信息,脚本来源于网络,做好搬运工,哈哈,相应的参考链接放在末位 shell版本: #!/bin/bash # CropID="xxxx" ...

  4. (转)淘淘商城系列——使用maven tomcat插件启动web工程

    http://blog.csdn.net/yerenyuan_pku/article/details/72672138 上文我们一起学习了怎样搭建maven工程,这篇文章我就来教大家一起学习怎样用to ...

  5. Winsock2_WSADATA

    使用Winsock2进行win下网络编程的第一步是初始化Winsock.其中需要创建一个WSADATA类型的变量,这个变量用来保存Windows socket的实现信息. typedef struct ...

  6. Which dispatch method would be used in Swift?

    In this example: protocol MyProtocol { func testFuncA() } extension MyProtocol { func testFuncA() { ...

  7. laravel-admin常见错误处理

    php artisan key:generate 新的laravle会有密钥不存在的问题,这时候我们执行这句话就可以生成秘钥了

  8. 编译压缩代码 MFCompress-src-1.01 :对‘***’未定义的引用

    提示 MFCompressD.o:在函数‘main’中:MFCompressD.c:(.text.startup+0x34a): 警告: the use of `tempnam' is dangero ...

  9. Python 判断是否存在Excel表

    Python 判断是否存在Excel表,无则生成,有则删除重建 import os import xlwt from openpyxl import workbook def sheet_method ...

  10. CGPathAddArc

    使用CGPathAddArc使UIView的Layer绕中心点旋转 2012-12-04 15:38 775人阅读 评论(0) 收藏 举报 animationAnimationiosiOSIOSlay ...