C++中常函数内部的this指针也是const类型的
代码中碰到一个奇怪的现象,在同样的函数中调用this指针,结果却有一个无法通过编译
// 读取连接信息
void ThirdWizardPage::ReadConnection()
{
QFile file("oracle.passwd");
if(!file.open(QIODevice::ReadOnly))
{
QMessageBox::information(this, tr("打开文件失败"),
tr("错误原因:%1").arg(file.errorString()));
return;
}
QDataStream in(&file);
Connection con;
int i = ;
while(!in.atEnd())
{
in >> con;
ui->comboBox->insertItem(i, con.strDatabase);
m_mapConnections.insert(i, con);
}
file.close();
} // 写入连接信息
void ThirdWizardPage::WriteConnection() const
{
QFile file("oracle.passwd");
if(!file.open(QIODevice::WriteOnly))
{
QMessageBox::information(const_cast<ThirdWizardPage*>(this),tr("打开文件失败"),
tr("失败原因:%1").arg(file.errorString()));
return;
}
QDataStream out(&file); for(int i = ;i < m_mapConnections.size();++i)
{
out << m_mapConnections[i];
}
file.close();
}
编译的错误提示是:
上面两个函数实现的功能是一个读取文件,一个写入文件,在两个函数中都使用到了QMessageBox::information函数,但是第二个函数中却必须将this指针强制转换成非const才能通过编译,仔细思考这个问题发现,是因为写入文件的函数定义为了常函数,即在函数体的大括号之前使用const修饰该函数。
以前学习C++primer的使用只知道定义为常函数是为了避免该函数修改类对象的成员变量。只是知道如果在常函数中修改了类的成员变量,那么编译时是通不过呢,至于为什么,怎么实现这样的控制的,却是不知道,只记住了怎么用。
下面说一下我自己的分析,众所周知,C++的所有成员函数都会有一个看不见的指针参数传入函数,该指针指向该对象(静态函数除外),那么可以推测,类的成员函数访问成员还是通过指针来访问的,即使有时候我们没有显示的使用this指针,系统也可能为我们默认填上,因为想要操作内存,归根结底还是要知道它存储在哪个位置,所以即便是那些没有指针的语言,我想,也是它的平台为它屏蔽了这些东西,而并不是这些东西不存在(这些东西是指指针)。
如此是否可以得出这样的结论:在常函数中,系统默认传入函数的this指针是const类型的。
那么,这样就可以解释的通了,如果在常函数中修改成员变量(即使不显示使用this指针,系统也会加上,因为要访问内存,必须使用指针),而现在的this指针又是const类型的,那么就会报错了,因此就可以实现限制在常函数中修改成员变量的功能了。
当然,以上全是凭借自己看到的现象以及对编程的一些悟性、理解做出的推测,不知道对不对。不过我的想法是,既然大师能想的出来,而大师也是人,只不过经验多些,所以自己如果思考的多了,也可能会成为大师的,嘿嘿,愿望。
最近开始看深入探索C++对象模型,就是讲C++的对象模型是如何实现的,希望在本书能将自己得出的这个结论验证一下。
C++中常函数内部的this指针也是const类型的的更多相关文章
- python中修改函数内部的变量会发生什么
最近写python遇到个函数内部变量使用外部变量的问题,现在总结下吧 #!/usr/bin/env python a = 100def su(): a = a + 1 print(a) s = su( ...
- C语言中的函数、数组与指针
1.函数:当程序很小的时候,我们可以使用一个main函数就能搞定,但当程序变大的时候,就超出了人的大脑承受范围,逻辑不清了,这时候就需要把一个大程序分成许多小的模块来组织,于是就出现了函数概念: 函 ...
- c++函数内部可以返回函数内部定义的指针 但是不能返回函数内部定义的数组
1.返回数组 // demo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<stdio.h> char *m ...
- Javascript中的函数(三)
一:概述 函数是进行模块化程序设计的基础,编写复杂的Ajax应用程序,必须对函数有更深入的了解.JavaScript中的函数不同于其他的语言,每个函数都是作为一个对象被维护和运行的.通过函数对象的性质 ...
- JS OOP -02 深入认识JS中的函数
深入认识JS中的函数: 1.概述,认识函数对象 2.函数对象和其他内部对象的关系 3.将函数作为参数传递 4.传递给函数的隐含参数:arguments 5.函数的apply,call方法和length ...
- 一些C/C++中的函数
项目中使用到的C/C++中的一些函数,记录下来加以理解和掌握. 1.memset( ) memset是计算机中C/C++语言函数.将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASC ...
- c++ 动态判断基类指针指向的子类类型(typeid)
我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 本文提供了两种方法 ( ...
- const指针和指向const的指针
int *const p=&a; 这是const指针,这种指针必须在定义时就给出它所指向的地址,否则会error:uninitialized const 'p'.const指针的指针本身是co ...
- 构造函数和初始化表、this指针与常函数、析构函数、拷贝构造与拷贝赋值(day05)
十四 构造函数和初始化表 ... 初始化表 )语法形式 class 类名{ 类名(形参表):成员变量1(初值),...{} }; )必须要使用初始化表的场景 -->如果有类 类型的成员变量,而该 ...
随机推荐
- Quartz学习笔记
:30发送email通知客户最新的业务情况. java.util.Timer和java.util.TimerTask Timer和TimerTask是能够完毕job schedule的两个jdk ...
- Android -- 经验分享(三)
目录 获取系统版本号 获取系统信息 获取安装路径和已安装程序列表 获取图片.应用名.包名 解决listview上Item上有按钮时item本身不能点击的问题 不让文本框输入中文 获取屏幕宽高 将Tab ...
- HDU 2897 邂逅明下 (博弈)
题意: 给你n.p.q,每次操作是令n减小 [p, q]区间中的数,当n < p时必须全部取完了,取完最后一次的人算输,问先手必胜还是必败. 解题思路: 这种非常类似巴什博弈,可以找出必胜区间和 ...
- 关于在Visual Studio 2008/2010 和Opencv平台下出现LINK : fatal error
http://blog.sina.com.cn/s/blog_9015f3230101bbef.html 关于在Visual Studio 2008/2010 和Opencv平台下出现LINK : f ...
- STL - Predicate - Binary Predicate(双参判断式)
Binary Predicate(双参判断式)的用途是:比较两个参数的特定属性 我们先建一个领域模型类: Person.h #ifndef _Domain_Models_Person_H_ #defi ...
- SQL语言 之 事务控制
一.概述 事务是一些数据库操作的集合,这些操作由一组相关的SQL语句组成(只能是 DML 语句),它们是一个有机的整体,要么全部成功执行,要么全部不执行.事务时数据库并发控制和恢复技术的基本单位. 事 ...
- Python set特点
set的特点 set的内部结构和dict很像,唯一区别是不存储value,因此,判断一个元素是否在set中速度很快. set存储的元素和dict的key类似,必须是不变对象,因此,任何可变对象是不能放 ...
- [Exception JavaWeb 1] - javax.el.PropertyNotFoundException: Property 'id' not found on ..........
好久不写Web应用了,今天碰到这个问题的时候,还一时半会没反应过来.实体类在jsp无法找对应的值. 最后发现是实体bean的属性的开头字母不能与次字母不能大写+小写或小写+大写,最后改成小写+小写就好 ...
- HBase权威指南 高清中文版 PDF(来自linuxidc)
内容提要 <HBase权威指南>由乔治(Lars George)著,探讨了 如何通过使用与HBase高度集成的Hadoop将 HBase的可 伸缩性变得简单:把大型数据集分布到相对廉价 ...
- HDU 2647--Reward【拓扑排序】
Reward Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...