char greeting[] = "hello";
char* p = greeting; //non-const pointer,non-const data
const char* p = greeting; //non-const pointer, const data
char* const p = greeting; //const pointer,non-const data
const char* const p = greeting; //const pointer, const data

以上为const面对指针时所产生的四种情况。

const 如出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针本身是常量;如果出现在星号两边,表示被指物和指针都是常量。

如果被指物是常量,const写在类型之前和类型之后都可以,意义相同,一下两种写法相同:

void f1( const type* pw );
void f2( type const* pw );

而对于STL迭代器。所有的迭代器作用就跟T*一样。声明迭代器为const就像声明一个const指针一样,表明迭代器不能指向不同的东西。如果想让迭代器指向的东西不可改变,则需要声明const_iterator。如下:

const vector<int>::iterator iter = vec.begin();     //如 T* const
*iter = ; //没有问题
iter++; //不可执行 vector<int>::const_iterator citer = vec.begin(); //如 const T*
*citer = ; //不可执行
citer++; //可以

const最具有威力的用法是面对函数声明时的应用:

class Rational {...};
const Rational operator* ( const Rational& lhs, const Rational& rhs); Rational a,b,c;
...
(a*b)=c;

如以上例子,对两个数值的乘积做了一次赋值,将operator*的回传声明为const可以预防这种没有意思的动作。

const成员函数

如果函数的返回类型是内置类型,那么如果改动函数返回值从来就不合法。如果返回类型为引用,则可以给返回值赋值。

class TextBlock{
public:
const char& operator[]( size_t position ) const
{
return text[position];
}
char& operator[](size_t position)
{
return text[position];
}
private:
string text;
};

如上类中,如果有以下调用:

TextBlock tb("hello");
cout << tb[];
const TextBlock ctb("world");
cout << ctb[];

tb直接调用类中的non-const成员函数,ctb调用的是const成员函数,如下代码:

cout << tb[];
tb[] = 'x';
cout << ctb[];
ctb[] = 'x';

ctb[0]='x'是不可以被执行的,因为const成员函数返回的是const的引用,并且const成员函数所使用的数据成员不可以被更改。

但是由于以上的方法却产生了以下问题:

class CTextBlock{
public:
char& operator[]( size_t position ) const
{
return pText[position];
}
private:
char* pText;
};

对于以上的类在如下调用时:

const CTextBlock cctb("hello");
char* pc = &cctb[];
*pc = 'J';

此时cctb为‘Jello’。
以上为 bitwise const 的观点,虽然const成员对象没有改变类的数据成员,但是整体上是改变了,这样的情况下const类成员意义不大,终究还是改变了其值。

于是产生了logical constness的观点:

class CTextBlock{
public:
size_t length() const;
private:
char* pText;
size_t textLength;
bool lengthIsValid;
};
size_t CTextBlock::length() const
{
textLength = strlen(pText);
lengthIsValid = true;
return textLength;
}

以上代码显然没法执行,因为在length为const成员函数不能改变数据成员。logical constness的观点如下:

class CTextBlock{
public:
size_t length() const;
private:
char* pText;
mutable size_t textLength;
mutable bool lengthIsValid;
};
size_t CTextBlock::length() const
{
textLength = strlen(pText);
lengthIsValid = true;
return textLength;
}

在const成员函数前加上mutable即可实现const成员函数改变数据成员。

effective c++(03)之const使用方法的更多相关文章

  1. const 使用方法具体解释

    const使用方法具体解释 面向对象是C++的重要特性.  可是c++在c的基础上新添加的几点优化也是非常耀眼的 就const直接能够代替c中的#define 下面几点非常重要,学不好后果也也非常严重 ...

  2. 【03】const

    [03]const 魔芋总结: 1,声明的是常量,一经声明,不得修改.必须声明的同时并赋值.否则报错. 2,只在声明所在的块级作用域内有效. 3,const命令声明的常量也是不提升,同样存在暂时性死区 ...

  3. const 修饰成员函数 前后用法(effective c++ 03)

    目录 const在函数后面 const修饰成员函数的两个作用 const在函数前面 总结 const在函数后面 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态 ...

  4. Effective JavaScript Item 21 使用apply方法调用函数以传入可变參数列表

    本系列作为Effective JavaScript的读书笔记. 以下是一个拥有可变參数列表的方法的典型样例: average(1, 2, 3); // 2 average(1); // 1 avera ...

  5. Effective Java 第三版——43.方法引用优于lambda表达式

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. C++中static、const使用方法简介

    众所周知,在c++中,static和const的使用方法是难点,也是重点,值得我们随时温习,所谓温故而知新是也. 下面我们首先说一说static. 1.static的作用 static变量的作用,主要 ...

  7. More Effective C++: 03异常

    C++的异常机制使得程序付出某些代价:资源泄漏的可能性增加了:写出具有你希望的行为的构造函数与析构函数变得更加困难:执行程序和库程序尺寸增加了,同时运行速度降低了等等. 但是为什么使用异常呢?C程序使 ...

  8. [03]java中的方法以及控制语句

    00 Java中的语句块 语句块(有时叫做复合语句),是用花括号扩起的任意数量的简单Java语句.块确定了局部变量的作用域.块中的程序代码,作为一个整体,是要被一起执行的.块可以被嵌套在另一个块中,但 ...

  9. 复习练习(03)jquery Css方法一步步升级

    jquery Css方法一步步升级 <script src="jquery-1.8.3.js"></script> <script type=&quo ...

随机推荐

  1. 处理.NET中的内存泄露

    Fabrice Marguerie是一位软件架构师和咨询师,他在MSDN发表了如何检测和避免.NET程序内存与资源泄漏的文章.此文章描述了编写.NET程序时可能发生的内存与资源泄漏,以及如何避免这些泄 ...

  2. [转]ASP.NET MVC 入门5、View与ViewData

    view在MVC模式中与用户进行最直接的接触,它负责数据的呈现.这里要注意一点就是,view只是负责数据的呈现,所以我们应该要尽量让view中不涉及业务逻辑的处理. 我们来添加一个Blog首页的vie ...

  3. T-SQL XQuery (XML路径查询) (转)http://blog.csdn.net/Beirut/article/details/8150116

    /* T-SQL 支持用于查询 XML 数据类型的 XQuery 语言的子集. XQuery 基于现有的 XPath 查询语言,并支持更好的迭代.更好的排序结果以及构造必需的 XML 的功能. 在前面 ...

  4. 用BigDecimal类实现Fibonacci算法

    Fibonacci(N)=Fibonacii(N-1)+Fibonacci(N-2) 其中 Fibonacci(0)=0;Fibonacci(1)=1 用循环或则递归实现Fibonacci算法很简单, ...

  5. HDU 3392 Pie(DP)

    题意:有一些男生女生,男生女生数量差不超过100 ,男生女生两两配对.要求求出一种配对方法,使每一对的高度差的和最小. 思路:(我是真的笨笨笨!!)设人少的一组人数为n,b[],人多的一组人数为m,g ...

  6. IT应聘者的简历应该是怎么样的?

    从去年到现在看了几百份简历,包括产品运营和产品设计师的职位.我不是 HR,只是想直接看到求职者的状况,看看是不是要换更准确的渠道去招聘对的人.我看简历的目的也很简单:找到没有什么问题且可能合适的人,然 ...

  7. 计算机网络协议包头赏析-UDP

    之前我们已经针对以太网.IP.TCP协议,进行了包头赏析.本次,我们继续UDP协议包头赏析. 提到TCP,想必大家会有所了解,它早已是家喻户晓的一个网络协议了,而UDP远没有他的大哥那么的有名,所以, ...

  8. 问题-[Delphi]PixelFormat 图像颜色的数据格式

     PixelFormat: (指定图像中每个像素的颜色数据的格式) Delphi                                        微软                  ...

  9. opencv数据结构-MAT结构详解

    1.定义 OpenCV中的C结构体有 CvMat 和 CvMatND,但后续的应用中指出 CvMat 和 CvMatND 弃用了,在C++封装中用 Mat 代替,另外旧版还有一个 IplImage,同 ...

  10. zend studio-如何更改字符集

    在加载一个项目的过程中很时候会因为字符集的不匹配从而导致项目文件显示为乱码,zend studio开发工具应该如何设置字符集呢: 打开[windows]-[preference]-[workspace ...