转载:http://www.cnblogs.com/little-sjq/p/9fed5450f45316cf35f4b1c17f2f6361.html

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成员函数 std::string isbn() const {return bookNo;}的更多相关文章

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

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

  2. 怎么在const成员函数里面调用非const成员函数?

    举个例子: 定义了一个类的const实例,怎么让他也能调用非能调用非const成员函数class foo{public:void test1() {cout << "I am n ...

  3. 类 this指针 const成员函数

    C++ Primer 第07章 类 7.1.2 ​Sales_data类的定义如下: #ifndef SALES_DATA_H #define SALES_DATA_H #include <st ...

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

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

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

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

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

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

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

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

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

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

  9. 【C++】const、volatile不能修饰没有this指针的成员函数

    一般所有的成员函数都只有一个复本,当不同的对象调用成员函数时,为了区分是哪个成员在调用,会传入this指针. 当调用有const.volatile修饰的成员函数时,会相应的传入一个const.vola ...

随机推荐

  1. Fixed table

    废话不多说,直接代码. <!DOCTYPE> <html> <head> <meta charset="utf-8"/> <s ...

  2. 系统相册中获取gif图片 保证取到的图片不会改变

    NSURL *imageRefURL = [info valueForKey:UIImagePickerControllerReferenceURL];                         ...

  3. spring_boot入门

    核心: 控制反转(Inversion of Control-IOC)和依赖注入(Dependency Injection-DI) Spring中两者是相同的, 控制反转是用依赖注入实现的. 这里, 依 ...

  4. Windows Dos命令下查看端口号,杀死端口

    PS:本文以 Redis 默认端口 6379 为例   1,首先查询该端口的 pid,使用命令 [netstat -ano | findstr 端口号]   F:\Program Files\Redi ...

  5. 适用于iOS7 UI的外描边图标素材下载

    我们知道ios7的界面设计是非常简约的,图标也不例外,iOS7的icon大部使用了扁平化的外描边风格设计,使得整体看起来十分简约.耐看,这次分享达人为大家收集将近600个漂亮的外描边图标下载,这些图标 ...

  6. 洛谷 p1141 01迷宫题解

    很长时间没发博客了,今天水一下 很多dalao说染色(普通的)过不了, 我怎么就过了 其实我也是今天才知道什么是染色(由@你听风在吼 dalao指导) 然后自己打了一个,也不知道叫不叫染色,反正是过了 ...

  7. springboot-i18n国际化

    简介 In computing, internationalization and localization are means of adapting computer software to di ...

  8. shell脚本,在指定目录下通过随机小写10个字母加固定字符串oldboy批量创建10个html文件。

    [root@localhost wyb]# cat test10.sh #!/bin/bash #使用for循环在/test10目录下通过随机小写10个字母加固定字符串oldboy批量创建10个htm ...

  9. ios lazying load

    初步写一些自己对于lazyload的看法吧.这篇文章主要针对普通view,对于image相关的的懒加载,准备过几天研究一下在写. 懒加载,又称为延迟加载.通常用法,你有一个UITextField类型的 ...

  10. ios之UISlider

    初始化一个Slider   UISlider *slider = [[UISlider alloc]initWithFrame:CGRectMake(0, 400,320 , 20)]; 滑块是一个标 ...