对指针来说,可以指定指针本身为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. iOS---UICollectionView自定义流布局实现瀑布流效果

    自定义布局,实现瀑布流效果 自定义流水布局,继承UICollectionViewLayout 实现一下方法 // 每次布局之前的准备 - (void)prepareLayout; // 返回所有的尺寸 ...

  2. VS2010 好用的javascript扩展工具

    工具1) JScript Editor Extensions 折叠代码 下载地址: JScript Editor Extensions 工具2) Javascript parser 以树形方式查的代码 ...

  3. vs2015 qt5.8新添加文件时出现“无法找到源文件ui.xxx.h”

    转载请注明出处:http://www.cnblogs.com/dachen408/p/7147135.html vs2015 qt5.8新添加文件时出现“无法找到源文件ui.xxx.h” 暂时解决版本 ...

  4. iTOP-6818开发板-Android4.4系统下RFID射频模块测试例程

    平台:迅为iTOP-6818开发板 系统:Android4.4版本 例程:RFID射频模块测试例程 rc522 驱动在 Android 系统的内核是默认集成的,用户可以在开发板上使用命令“ls /de ...

  5. 引入msword

    找到解决方法了:不是直接引入mswork.tlh文件的,该文件是#import "C:\\Program Files\\Microsoft Office\\Office12\\MSWORD. ...

  6. Vue+Bootstrap实现购物车程序(1)

    先看下案例效果:(简单的数量控制及价格运算) 代码: <!DOCTYPE html> <html> <head lang="en"> <m ...

  7. nginx配置实现负载均衡

    一.负载均衡的作用 1.转发功能 按照一定的算法[权重.轮询],将客户端请求转发到不同应用服务器上,减轻单个服务器压力,提高系统并发量. 2.故障移除 通过心跳检测的方式,判断应用服务器当前是否可以正 ...

  8. MRC转ARC(2)

    春节前抽空花了一天的时间将手头的工程从MRC转成了ARC,然后陆陆续续地修复一部分因为转ARC引起的内存泄漏和崩溃,到目前为止工程也算是比较稳定了,抽空记上一笔.(虽说这种事情这辈子估计都只会做这么一 ...

  9. cc.Node—坐标系统

    cc.Vec21: cc.Vec2 二维向量坐标, 表结构{x: 120, y: 120}; cc.v2(x, y) 创建一个二维向量 cc.p() 创建一个二外向量;2: cc.pSub: 向量相减 ...

  10. C++ 指针形参和指针引用形参的原理分析

    C++ 函数的参数传递可以分为:值传递和引用传递. 两者的最大区别也很简单,如果该函数的参数只是读的话,值传递就可以满足.如果该函数的参数需要进行修改并返回的时候,就应该进行引用传递. C++指针作为 ...