在c++中,我们可以用const来定义一个const对象,const对象是不可以调用类中的非const成员函数,这是为什么呢?下面是我总结的一些原理。

假设有一个类,名字为test代码如下:

 class test{
  int i;
public:
  void print();
  test(int i);
};

我们知道c++在类的成员函数中还会隐式传入一个指向当前对象的this指针,所以在test类中,实际的print函数应该是这样的void print(test * this);,这代表一个指向test对象的指针this被传入到了print函数中

假如现在我们用test类创建一个对象,

 test obj1();
obj1.print();

第二句,obj1.print();其实相当于print(&obj1);,即把当前的对象obj1的指针传递到print()函数,这是没问题的

如果用test类创建一个const对象,然后去调用print()函数呢?这就会出现问题

const test obj2();
obj2.print();

这时obj2对象的指针就会传递给test *this 指针,而obj2的地址翻译成指针类型应该是这样的,const test* this,即这时会出现类型不匹配的错误,在visual studio 中会出现类似于下面的错误:

4

所以通过上面的说明,我们知道了为什么const 对象不能调用非const成员函数。

下面解释为什么const 对象可以调用const成员函数,

 class test{
public:
void print()const;
};

前面我们把非const成员函数print(),翻译了一下,同样const成员函数也要翻译,void print()const; 可以翻译成 void print(const test* this);,那么常量对象的地址翻译是const test* this; 是和void print() const;中this指针的类型是一样的,所以常量对象可以调用const成员函数。

有一个点要注意,在c++中其实是有最小权限原则的,非const对象是可以调用const成员函数的

为什么const对象只能调用const成员函数,而不能调用非const成员函数?的更多相关文章

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

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

  2. 12.C++-构造函数与析构函数调用顺序,const成员函数,const对象

    单个对象创建时,构造函数的调用顺序 1.首先判断该对象的类是否拥有父类,若有则先调用父类的构造函数 2.判断该对象的成员是否是其它类的成员,若是则调用成员变量的构造函数(调用顺序和声明顺序相同) 3. ...

  3. const和非const函数重载

    成员函数后面加const,表示在该函数中不能对类的数据成员进行改变,比如下面的代码: #include <stdio.h> class A { private: mutable int a ...

  4. C++解析(13):临时对象与const对象

    0.目录 1.临时对象 2.const对象 3.类成员 4.小结 1.临时对象 一个有趣的问题--下面的程序输出什么?为什么? #include <stdio.h> class Test ...

  5. 第24课经典问题(中)-----关于const对象的疑问

    关于const对象的疑问const关键字能否修饰类的对象?如果可以,有什么特性?const关键字能够修饰对象const修饰的对象为只读对象只读对象的成员变量不允许被改变.(对象是只读的,成员变量不允许 ...

  6. 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象, const 指针和指向 const 对象的指针, const 对象的引用

    [源码下载] 不可或缺 Windows Native (18) - C++: this 指针, 对象数组, 对象和指针, const 对象,  const 指针和指向 const 对象的指针, con ...

  7. const对象,指向const对象的指针 和 const 指针

    const对象: const对象声明时必须赋初值,该值在编译阶段确定,不可在程序中修改. const修饰符既可放在类型名前也可放在类型名后,通常放在类型名前.不过放在类型名后易于理解. const i ...

  8. 临时变量不能作为非const引用

    转自:http://blog.csdn.net/u011068702/article/details/64443949 1.看代码 2.编译结果 3.分析和解决 就拿f(a + b)来说,a+b的值会 ...

  9. Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称

    手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...

随机推荐

  1. 35. CentOS-6.3安装拼音输入法

    安装方法: su root yum install "@Chinese Support"      // 安装中文输入法 exit 装好后,在“系统-->首选项”就会看到有“ ...

  2. HTML5 Canvas 小例子 旋转的图片

    <一>CSS部分 @charset "utf-8"; *{ padding:; margin:; outline: none; } #canvas{ position: ...

  3. div 标签

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. 19 python unit4 常用模块练习题&总结

      1.logging模块有几个日志级别? logging模块共有5个级别,分别是: DEBUG INFO WARNING ERROR CRITICAL logging的日志可以分为 debug(), ...

  5. 代码报错记录-MAVEN-2

    报错: 编译错误,程序包org.junit找不到 原因: 这个是父项目,报错是在子项目中,子项目使用了父项目的junit包,由于scope是test,导致子项目在编译时找不到junit, 修改: 将父 ...

  6. lzo文件压缩,解压

    LZOP命令安装 yum install lzop lzop命令基本操作命令 # lzop -v test # 创建test.lzo压缩文件,输出详细信息,保留test文件不变 # lzop -Uv ...

  7. 3.3 JSP内置对象概述

    1.request 1.1 request获取页面传来的参数,参数通过浏览器网址和后面添加?的方式传达. 传参:”show.jsp?id=001” 获取参数:request.getParameter( ...

  8. ArcMap导入图层出现General function failure问题

    问题描述: 使用ArcMap的FeatureClassToFeatureClass命令导入图层,出现如下图的错误提示: 解决方法: 参考http://forums.esri.com/thread.as ...

  9. MySQL Installation of system tables failed!

    刚开始学习Linux,就遇到了问题. 当在RedHat下安装MySQL时提示如下错误,请高手给点指点,谢谢: rpm -vih  MySQL-server-community-5.0.96-1.rhe ...

  10. pyspark dataframe 格式数据输入 做逻辑回归

    该方法好处是可以调节阈值,可调参数比其他形式模型多很多. [参照]http://blog.csdn.net/u013719780/article/details/52277616 [3种模型效果比较: ...