C++ Primer 第07章 类

7.1.2

​Sales_data类的定义如下:

  1. #ifndef SALES_DATA_H
  2. #define SALES_DATA_H
  3. #include <string>
  4. #include <iostream>
  5. class Sales_data {
  6. public:
  7. std::string isbn() const {return bookNo;}
  8. Sales_data& combine(const Sales_data&);
  9. double avg_price() const;
  10. private:
  11. std::string bookNo;
  12. unsigned units_sold = 0;
  13. double revenue = 0.0;
  14. };
  15. Sales_data add(const Sales_data&, const Sales_data&);
  16. std::ostream &print(std::ostream&, const Sales_data&);
  17. std::istream &read(std::istream&, const Sales_data&);
  18. #endif

注意第8行:

  1. std::string isbn() const {return bookNo;}

这里const的作用是修改隐式this指针的类型,默认情况下,this的类型是指向类类型非常量版本的常量指针。例如在Sales_data成员函数中,this的类型是Sales_data *const,即类一旦实例化一个对象后,this指向这个对象,是不能改变的,但是对象本身可以变(通俗的讲,this保存的地址不能变,但是*this指向的内容是可以变的,所以*this是非常量,不可以将this绑定一个常量对象),举个例子:

  1. const int a = 5;     //a为整型常量
  2. int *const pa = &a; //pa是常量指针,但是*pa可以变,但是a又是常量,所以报错

所以这样就会带来一个问题:我们不能在一个常量对象上调用普通成员函数,测试如下:

去掉const,测试代码如下:

  1. #include "Sales_data.h"
  2. int main()
  3. {
  4. Sales_data data1;
  5. std::cout << data1.isbn() << std::endl;
  6. return 0;
  7. }

结果OK,data1是非常量,调用普通成员函数没有问题,下面做一个改变,将data1声明成常量

  1. #include "Sales_data.h"
  2. int main()
  3. {
  4. const Sales_data data1;
  5. std::cout << data1.isbn() << std::endl;
  6. return 0;
  7. }

​CodeBlocks编译报错

  1. error: passing 'const Sales_data' as 'this' argument of 'std::string Sales_data::isbn()' discards qualifiers [-fpermissive]

如果isbn是一个普通函数而this是一个普通指针参数,则我们应该把this声明成const Sales_data *const。毕竟,在isbn的函数体内不会改变this所指向的对象,所以把this设置为指向常量的指针有助于提高函数的灵活性。

然而,this是隐式的并且不会出现在参数列表中,所以在哪儿将this声明成指向常量的指针就成为我们必须面对的问题。C++语言的做法是允许把const关键字放在成员函数的参数列表之后,此时,紧跟在参数列表后面的const表示this是一个指向常量的指针。像这样使用const的成员函数被称作常量成员函数(const member function)。

可以把isbn的函数体想象成如下形式:

  1. //伪代码,说明隐式的this指针是如何使用的
  2. //下面的代码是非法的:因为我们不能显示地定义自己的this指针
  3. //谨记此处的this是一个指向常量的指针,因为isbn是一个常量成员
  4. std::string Sales_data::isbn(const Sales_data *const this)
  5. { return this->isbn; }

​因为this是指向常量的指针,所以常量成员函数不能改变调用它的对象的内容。在上例中,isbn可以读取调用它的对象的数据成员,但是不能写入新值。

note:​常量对象,以及常量对象的引用或指针都只能调用常量成员函数。

类 this指针 const成员函数的更多相关文章

  1. 类 this指针 const成员函数 std::string isbn() const {return bookNo;}

    转载:http://www.cnblogs.com/little-sjq/p/9fed5450f45316cf35f4b1c17f2f6361.html C++ Primer 第07章 类 7.1.2 ...

  2. 类1(this指针/const成员函数/类作用域/外部成员函数/返回this对象的函数)

    假设我们要设计一个包含以下操作的 Sales_data 类: 1.一个 isbn 成员函数,用于返回对象的 book_no 成员变量 2.一个 combine 成员函数,用于将一个 Sales_dat ...

  3. 【c++】类中的const成员

    const成员变量 举个例子 #include <iostream> using namespace std; class A { public: A(int size) : SIZE(s ...

  4. C++类的const成员函数、默认的构造函数、复制形参调用函数(转)

    C++类的const成员函数 double Sales_item::avg_price() const { } const关键字表明这是一个const成员函数,它不可以修改Sales_item类的成员 ...

  5. c++中的const参数,const变量,const指针,const对象,以及const成员函数

    const 是constant 的缩写,“恒定不变”的意思.被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性.所以很多C++程序设计书籍建议:“Use const whe ...

  6. 类的const成员函数,是如何改变const对象的?

    我们知道类里面的const的成员函数一般是不允许改变类对象的,但是我们知道const 类型的指针是可以强制类型转出成非const指针的,同样的道理,this指针也可以被强制类型转换 class Y{ ...

  7. C++之const类成员变量,const成员函数

    const修饰类的成员函数 const修饰变量一般有两种方式:const T *a,或者 T const *a,这两者都是一样的,主要看const位于*的左边还是右边,这里不再赘述,主要来看一下当co ...

  8. 11、C++之const类成员变量,const成员函数

    //转载 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变. 在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 cons ...

  9. const成员函数可以将非const指针作为返回值吗?

    先给出一段代码 class A { int *x; public: int *f() const { return x; } }; 成员函数f返回指向私有成员 x 的非常量指针,我认为这会修改成员x ...

随机推荐

  1. js解决网页无法复制文字的问题

    碰到有些网站,站长禁止了右键,或者用其它方法不让复制网页的文字,弄的好烦人啊,虽然这是小把戏,但多多少少造成了一些不方便,前几天发现这个解决不能复制问题的小方法,一行代码即搞定,就是下面这行: jav ...

  2. NET调用Java之100-Continue的坑

    场景:这段时间开发的时候遇到了需要NET调用java的restful api的情况,java端用的服务器是tomcat,框架是spring boot,net调用java端的接口之后只要java端的接口 ...

  3. 复杂事件处理引擎—Esper参考(事件部分)

    声明:Esper官方未提供中文文档,以后更新的大部分内容,均来自官方文档.本人英语小白一枚,翻译内容仅供参考.有些翻译确实不忍直视,君可略过. (有人可能会说,翻译的不好不如不翻,可能会误人子弟:不过 ...

  4. 五个新知识:微软SHA2补丁,亚信专业工具,微软官方文档,使用过期签名(附官方推荐链接),注意使用具有UAC的CMD

    五个新知识:微软SHA2补丁,亚信专业工具,微软官方文档,使用过期签名 不支持SHA2算法的计算机更新补丁:https://technet.microsoft.com/zh-CN/library/se ...

  5. Basefragment的封装使用

    1.前言 封装作为面向对象的三大特性之一,在我们平时的coding过程用的那是非常的多的.大多数时候,我们可以根据封装情况评判代码的质量水平. 本文主要讲解的是fragment的封装.大体上,在项目的 ...

  6. android数据保存

    永久保存数据的方法:1.Shared Preferences 以键值对的形式存储基本数据类型( booleans, floats, ints, longs, and strings),存储的数据在限制 ...

  7. HDU_2053

    Problem Description There are many lamps in a line. All of them are off at first. A series of operat ...

  8. CF-Approximating a Constant Range

    Description When Xellos was doing a practice course in university, he once had to measure the intens ...

  9. HDU-3665(单源最短路)

    Problem Description XiaoY is living in a big city, there are N towns in it and some towns near the s ...

  10. java foreach记录

    实现原理解释: http://blog.csdn.net/a596620989/article/details/6930479 http://stackoverflow.com/questions/8 ...