速度 
#include <iostream>
using namespace std;
class TextBlock
{
private:
string text;
public:
TextBlock(string s)
{
text = s;
}
const char& operator[](size_t position) const
  {return text[position]; } char& operator[](size_t position)
{return text[position]; }
};
int main()
{
TextBlock tb("hello");
const TextBlock ctb("world");
cout << tb[0];
cout << ctb[0];
return 0;
}

关于其中的:const char& operator[](size_t position) const

第一个const要是不带的话会报:error: invalid initialization of reference of type ‘char&’ from expression of type ‘const char’
难道认为text[position]是个const char了 因为第2个const ??
第2个const的作用是为了重载函数 Mar 14,2014
关于第1个const找到一个好解释:对于const函数,如果返回值为引用,则必须返回Const引用 ,如果返回的是指针或者一般值,就不需要了
详细参见 http://bbs.csdn.net/topics/390731394?page=1#post-396953946

2)iterator认为是一个T*,这个是一个封装了的指针。所以const iterator意味着是常指针。const_iterator 意味着const T* :指向的内容不可变,这个与const iterator是相反的。

再转一个const的blog

C++中const重载

分类: C/C++ 2010-06-02 22:53 605人阅读 评论(0) 收藏 举报

众所周知,C++实现函数重载有两种情况:函数参数的类型不同,参数的个数不同。而与函数的返回值没有什么关系。

需要注意的是在如下情况下:

  1. float f1(float a, float b)
  2. {
  3. //
  4. }
  5. flaot f1(float a, float b, float c = 0)
  6. {
  7. //
  8. }

下面的调用会产生歧义:

  1. f1(2.0, 2.0);

言归正传,看下面一段代码:取自Effective C++

  1. class TextBlock {
  2. public:
  3. ...
  4. const char& operator[] (std::size_t position) const
  5. {return text[position];}
  6. char& operator[] (std::size_t position)
  7. {return text[position];}
  8. private:
  9. std::string text;
  10. }
  11. TextBlock tb("Hello");
  12. std::cout << tb[0];
  13. const TextBlock ctb("World");
  14. std::cout << ctb[0];

const char& operator[] (std::size_t position) const

后一个const参与对重载函数的区分,这样在参数类型个数相同的情况下形成一种新的重载形式。

需要注意:常成员函数是常对象唯一的对外接口,使用使应该注意。常成员函数不能更新对象的数据成员,也不能调用该类中的普通成员函数。

这就是为什么const TextBlock ctb("World");会调用const char& operator[] (std::size_t position) const;的原因,包含了C++的隐式调用。

const

常量

函数

it

分类: C/C_plus_plus

今天在做一个趋势笔试题的时候,才让我有了系统把const关键字好好总结一下的冲动,因为这个关键词大大小小好多地方都出现过,出现频率非常高,而每次只是简短的把答案看了一下,没有真正将其整个用法弄透,马上要找工作了,为避免悲剧再次发生,不得不引起我的重视,这才有了这篇博文。

    首先,一看到const关键字,我们的第一反应就是定义常量。的确,这没有错,const就是constant的缩写嘛,但是事实上他的用法远不止这些。接下来我们一一来讲解。
    在C程序中,const的用法主要有定义常量、修饰函数参数和修饰函数返回值。而在C++程序中,它除了上述功能外,还可以修饰函数的定义体,定义类中某个成员函数为恒态函数,即不改变类中的数据成员。对于定义常量的用法,这里就不多说了,重点看一下修饰函数参数、修饰函数返回值以及修饰函数的定义体。
    1)修饰函数参数
    首先如果该参数用于输出,那么无论是采用指针传递还是引用传递,都不能加const修饰。所以const只能用于修饰输入参数。这里又分三种情况:输入参数采用值传递还是指针传递还是引用传递。
    (1)如果采用值传递,由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不需要加const 修饰。
     例如,对于函数void Func1(int x),写成void Func1(const int x)一点意义也没有。同理,对于void Func2(A a)也不需要写成void Func2(const A a),其中A为用户自定义的对象类型。
    (2)如果采用指针传递,那么加const可以防止函数体内部对该参数进行改变,起到保护作用。
     例如,假设StringCopy函数定义为:void StringCopy(char *strDest, const char *strSrc),那么,如果函数体试图改变strSrc的内容,编译器将报错。
    (3)如果采用引用传递,
     首先我们来说一下,为什么要引入引用传递这种方法。原因是:对于非内部数据类型的参数而言,象void Func(A a) 这样声明的函数注定效率比较底。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。为了提高效率,可以将函数声明改为void Func(A& a)。这样一来,根据引用传递的定义,只是借用了参数的别名,不需要产生临时对象。
      但是,这样一来,当函数体中改变了参数a的值后,相应的传递的原始值也会相应改变。所以如果不希望改变原始参数,只需要在前面加上const修饰,这样一来,函数最终定义为void Func(const A& a)。同理,是否应将void Func(int x) 改写为void Func(const int &x),以便提高效率?完全没有必要,因为内部数据类型的参数不存在构造、析构的过程,而复制也非常快,“值传递”和“引用传递”的效率几乎相当。
     总结一下const作为函数输入参数的用法:
     (1)对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。
         (2)对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。
 
      2)修饰函数的返回值
      根据上面的思路,这里也分三种情况,即值传递、指针传递、引用传递。
      (1)如果函数返回值采用“值传递”方式,由于函数会把返回值复制到外部临时的存储单元中,加const 修饰没有任何价值。
     例如,不要把函数int GetInt(void) 写成const int GetInt(void)。同理不要把函数A GetA(void) 写成const A GetA(void),其中A 为用户自定义的数据类型。
    (2)如果函数返回值采用“指针传递”方式,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。
     例如,定义函数为:const char *GetString(void),那么char *str = GetString()将会出现编译错误。应该写成const char *str = GetString()。
    (3)如果函数返回值是采用“引用传递”方式,它的意义在于能提供啊效率,而这种方式使用场合并不多。这个时候,一定要搞清楚函数究竟是想返回一个对象的“拷贝”还是仅返回“别名”就可以了,否则程序会出错。
     例如,对于类的重载赋值函数A & operate = (const A &other),如果不加cons修饰,则定义A a, b, c;(a = b) = c,程序合法,但是如果加上const修饰,即const A & operate = (const A &other),则程序会报错。
 
       3)修饰函数的定义体。
       定义const函数,只需要将const关键字放在函数声明的尾部。任何不会修改类的数据成员的函数都应该声明为const 类型。如果在编写const 成员函数时,不慎修改了数据成员,或者调用了其它非const 成员函数,编译器将报错,这无疑会提高程序的健壮性。
    例如,以下程序中,类stack 的成员函数GetCount 仅用于计数,从逻辑上讲GetCount 应当为const 函数。编译器将指出GetCount 函数中的错误。
class Stack
{
public:
  void Push(int elem);
  int Pop(void);
  int GetCount(void) const; // const 成员函数
private:
  int m_num;
  int m_data[100];
};
int Stack::GetCount(void) const
{
  ++ m_num; // 编译错误,企图修改数据成员m_num
  Pop(); // 编译错误,企图调用非const 函数
  return m_num;
}
 
    到这里,const关键字的讲解就结束了。以下是几点使用const的几点规则。
    1) const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数
    2) const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的。
    3) const成员函数不可以修改对象的数据,不管对象是否具有const性质.它在编译时,以是否修改成员数据为依据,进行检查。

4) 然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的

[EffectiveC++]item03:尽可能使用const 并且转载一篇关于const函数的博客的更多相关文章

  1. 转载: 使用vue全家桶制作博客网站 HTML5 移动网站制作的好教程

    使用vue全家桶制作博客网站   前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用vue全家桶制作的博客网站 概述 该项目是基于vue全家桶(vue. ...

  2. 几篇不错的基础css博客转载

    CSS 巧用 :before和:after:http://web.jobbole.com/85083/ css清除元素间距:http://ouvens.github.io/frontend-css/2 ...

  3. python 下划线的使用(转载:安生犹梦 新浪博客)

    Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx      不能用'from module import *'导入 __xxx__ 系统定义名字 __xxx    类中的私有变量名 核 ...

  4. Swift中可选类型(Optional)的用法 以及? 和 ! 的区别 (转载博客,知识分享)

    本文转载自:代码手工艺人的博客,原文名称:Swift之 ? 和 ! Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,也就是说变量不会有默认值,所以要求使用变量之 ...

  5. [EffectiveC++]item3:尽可能使用const

    将某些东西声明为const可以帮助编译器检测出错误用法,const 编译器强制实施bitwise constness,但是你code的时候应该使用“概念上的常量性” 当const和non-const成 ...

  6. 转载----C/C++ 中 const 修饰符用法总结

    感谢原创作者,写的好详细.不忍错过,所以转载过来了... 原文地址: https://www.cnblogs.com/icemoon1987/p/3320326.html 在这篇文章中,我总结了一些C ...

  7. 转载:string、const char*、 char* 、char[]相互转换

    本文转自:https://blog.csdn.net/rongrongyaofeiqi/article/details/52442169 一:转化总结形式如下: 使用时,要对源格式和目标格式进行初始化 ...

  8. 好文推荐:转载一篇别人kaggle的经验分享

    转载:https://www.toutiao.com/i6435866304363627010/ 笔者参加了由Quora举办的Quora Question Pairs比赛,并且获得了前1%的成绩.这是 ...

  9. Trie树(c++实现)——转载自jihite的博客

    Trie树(c++实现)   原理 先看个例子,存储字符串abc.ab.abm.abcde.pm可以利用以下方式存储 上边就是Trie树的基本原理:利用字串的公共前缀来节省存储空间,最大限度的减少无谓 ...

随机推荐

  1. APU (美国AMD公司研发的加速处理器)

    APU(Accelerated Processing Unit)中文名字叫加速处理器,是AMD“融聚未来”理念的产品,它第一次将中央处理器和独显核心做在一个晶片上,它同时具有高性能处理器和最新独立显卡 ...

  2. 第一章:初识PHP

    Web程序工作原理介绍? 工作方式? 浏览器首先向Web服务器发出请求,Web服务器对请求做出响应,将响应数据发送给客户端浏览器,通常是一个HTML文件,然后通过浏览器把HTML文件信息显示在屏幕上. ...

  3. [转]Http请求中Content-Type讲解以及在Spring MVC中的应用

    本文转自:http://blog.csdn.net/blueheart20/article/details/45174399 引言: 在Http请求中,我们每天都在使用Content-type来指定不 ...

  4. input type =text,按回车键自动提交

    1.当form表单中只有一个<input type="text" name='name' />时按回车键将会自动将表单提交 <form id='form1' ac ...

  5. 如鹏网学习笔记(五)MySql基础

    MySQL基础 一.数据库概念 1,网友装备信息.论坛帖子信息.QQ好友关系信息.学籍管理系统中的学生信息等都要“持久化”的保存到一个地方, 如果通过IO写到文件中,那么会非常麻烦,而且不利于多人共享 ...

  6. java线程总结2--wait/notify(all)/sleep以及中断概念

    上一篇关于线程的博客简单梳理了一下多线程的一些基本概念,今天这篇博客再进行多线程编程中一些核心的方法进行简单的梳理和总结,主要是wait,sleep和notify方法以及中断的概念 一.中断概念. 在 ...

  7. 1、类、封装(私有private、this关键字)

    类与对象 对象在需求中的使用 ​ 对面向对象有了了解之后,我们来说说在具体问题中如何使用面向对象去分析问题,和如何使用面向对象. ​ 我们把大象装冰箱为例进行分析. ​ 在针对具体的需求,可以使用名词 ...

  8. 撩课-Python-每天5道面试题-第5天

    一. 给定一个圆心和半径, 以及一个点坐标, 判定该点是否在圆内; 例如: 用户输入圆心: (1, 2) 半径: 2.5 测试点为(2, 2)结果: 判定测试点是在圆内 思路: 结合勾股定理, 计算测 ...

  9. 撩课-Java每天10道面试题第1天

    1.简述JDK.JRE.JVM? 一.JDK JDK(Java Development Kit) 是整个JAVA的核心, 包括了Java运行环境(Java Runtime Envirnment), 一 ...

  10. Ubuntu重启网卡的三种方法

    一.network利用root帐户# service network restart 或者/etc/init.d/networking restart 二.ifdown/ifup# ifdown et ...