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. IIS7配置https

    To Install an SSL Certificate in Microsoft IIS 7 Click Start, mouse-over Administrative Tools, and t ...

  2. Oracle.ManagedDataAccessDTC.dll 使用

    ODP.NET, Managed Driver Setup This section explains the setup and configuration steps required for u ...

  3. [CODEVS1295]N皇后(位运算+搜索)

    题目描述 Description 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个皇后,任 ...

  4. Lua包管理工具Luarocks详解 - 15134559390的个人空间 - 开源中国社区

    Lua包管理工具Luarocks详解 - 15134559390的个人空间 - 开源中国社区 Lua包管理工具Luarocks详解

  5. 用java面向对象的思想实现的汉诺塔问题

    package hanoi.com; public class Disc { private String name; private int level; public Disc(){ name = ...

  6. STM32F103 与 STM32F407引脚兼容问题

    ===========突袭网收集的解决方案如下=========== 解决方案1: STM32F103有的功能407都有,并且这些功能的引脚完全兼容,只是程序不同而已...而STM32F407有的功能 ...

  7. JAVA_3lesson

    程序设计守则 为了增加程序的可扩展性,维护性.可以采用interface, abstract   可以抽象出来:共同的方法,属性   开发系统时,主体构架使用接口,接口构成了系统的骨架.   要遵循开 ...

  8. TOR的使用

    使用步骤: 1.配置,该计算机是否需要通过代理访问互联网?选否 2.该计算机的防火墙是否仅允许特定端口的互联网连接?选否 3.互联网服务提供商(ISP)是否对Tor网络连接进行了封锁或审查?选是 4. ...

  9. Objective-C-使用NSMutableURLRequest发送POST请求,使用NSJSONSerialization解析JSON字符串

    NSString *reqData = @"Data="; NSData *postDatas = nil; NSString *urlPath = @"url" ...

  10. 模拟等待事件row lock waits

    是索引块分裂引起的锁等待,往往与enq: TX - index contention 伴随产生,enq:TX - index contention的解释. Waits for TX in mode 4 ...