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. mysql 分区信息查看

    select partition_name part,partition_expression expr,partition_description descr,table_rows from INF ...

  2. WINDOW下php开启pgsql拓展

    操作步骤: 1.修改php.ini,去掉“extension=php_pgsql.dll ”和“extension=php_pdo_pgsql.dll ”前的分号.2.确认C:\php\ext\下ph ...

  3. HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR的使用 php

    参考来源:http://qq398705749.iteye.com/blog/963818 php中HTTP_X_FORWARDED_FOR 和 REMOTE_ADDR的使用 1.REMOTE_ADD ...

  4. WinForm------DateTime获取月第一天和最后一天取法

    转载: http://blog.csdn.net/livening/article/details/6049341/ 代码: /// <summary> /// 取得某月的第一天 /// ...

  5. BZOJ3399: [Usaco2009 Mar]Sand Castle城堡

    3399: [Usaco2009 Mar]Sand Castle城堡 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 22  Solved: 17[Sub ...

  6. HDU_2036——多边形面积,行列式计算

    Problem Description “ 改革春风吹满地, 不会AC没关系; 实在不行回老家, 还有一亩三分地. 谢谢!(乐队奏乐)”话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也 ...

  7. HDU_2028——求多个数的最小公倍数

    Problem Description 求n个数的最小公倍数.   Input 输入包含多个测试实例,每个测试实例的开始是一个正整数n,然后是n个正整数.   Output 为每组测试数据输出它们的最 ...

  8. WC2015流水账

    THU那四场考试没考好,只有20+名.这也许是我OI生涯中最后一场吧(已确认是最后一场),真是感慨万千. day0 搬进浙大宿舍404房间(神房间号),四个人一间.中午发现学军伙食相当良心,是我参加的 ...

  9. 百度全站变https

    今天打开百度首页,突然发现,百度的网址变为 https://www.baidu.com/,如下图: 好嘛,以后再也不怕别人使用抓包工具查看我在百度的搜索数据了.当年的Duck Duck Go就是因为是 ...

  10. Jenkins - 持续集成

    Jenkins是一个开源软件项目,旨在提供一个开放易用的软件平台,使持续集成变成可能. Jenkins,之前叫做Hudson,是基于Java开发的一种持续集成工具,用于监控秩序重复的工作,包括: 1. ...