C++中常函数内部的this指针也是const类型的

代码中碰到一个奇怪的现象,在同样的函数中调用this指针,结果却有一个无法通过编译

 1 // 读取连接信息
 2 void ThirdWizardPage::ReadConnection()
 3 {
 4     QFile file("oracle.passwd");
 5     if(!file.open(QIODevice::ReadOnly))
 6     {
 7         QMessageBox::information(this, tr("打开文件失败"),
 8                                  tr("错误原因:%1").arg(file.errorString()));
 9         return;
10     }
11     QDataStream in(&file);
12     Connection con;
13     int i = 0;
14     while(!in.atEnd())
15     {
16         in >> con;
17         ui->comboBox->insertItem(i, con.strDatabase);
18         m_mapConnections.insert(i, con);
19     }
20     file.close();
21 }
22
23 // 写入连接信息
24 void ThirdWizardPage::WriteConnection() const
25 {
26     QFile file("oracle.passwd");
27     if(!file.open(QIODevice::WriteOnly))
28     {
29         QMessageBox::information(const_cast<ThirdWizardPage*>(this),tr("打开文件失败"),
30                                  tr("失败原因:%1").arg(file.errorString()));
31         return;
32     }
33     QDataStream out(&file);
34
35     for(int i = 0;i < m_mapConnections.size();++i)
36     {
37         out << m_mapConnections[i];
38     }
39     file.close();
40 }

编译的错误提示是:

上面两个函数实现的功能是一个读取文件,一个写入文件,在两个函数中都使用到了QMessageBox::information函数,但是第二个函数中却必须将this指针强制转换成非const才能通过编译,仔细思考这个问题发现,是因为写入文件的函数定义为了常函数,即在函数体的大括号之前使用const修饰该函数。

以前学习C++primer的使用只知道定义为常函数是为了避免该函数修改类对象的成员变量。只是知道如果在常函数中修改了类的成员变量,那么编译时是通不过呢,至于为什么,怎么实现这样的控制的,却是不知道,只记住了怎么用。

下面说一下我自己的分析,众所周知,C++的所有成员函数都会有一个看不见的指针参数传入函数,该指针指向该对象(静态函数除外),那么可以推测,类的成员函数访问成员还是通过指针来访问的,即使有时候我们没有显示的使用this指针,系统也可能为我们默认填上,因为想要操作内存,归根结底还是要知道它存储在哪个位置,所以即便是那些没有指针的语言,我想,也是它的平台为它屏蔽了这些东西,而并不是这些东西不存在(这些东西是指指针)。

如此是否可以得出这样的结论:在常函数中,系统默认传入函数的this指针是const类型的。

那么,这样就可以解释的通了,如果在常函数中修改成员变量(即使不显示使用this指针,系统也会加上,因为要访问内存,必须使用指针),而现在的this指针又是const类型的,那么就会报错了,因此就可以实现限制在常函数中修改成员变量的功能了。

当然,以上全是凭借自己看到的现象以及对编程的一些悟性、理解做出的推测,不知道对不对。不过我的想法是,既然大师能想的出来,而大师也是人,只不过经验多些,所以自己如果思考的多了,也可能会成为大师的,嘿嘿,愿望。

最近开始看深入探索C++对象模型,就是讲C++的对象模型是如何实现的,希望在本书能将自己得出的这个结论验证一下。

C++中常函数内部的this指针也是const类型的

时间: 2024-10-07 09:17:41

C++中常函数内部的this指针也是const类型的的相关文章

python中修改函数内部的变量会发生什么

最近写python遇到个函数内部变量使用外部变量的问题,现在总结下吧 #!/usr/bin/env python a = 100def su(): a = a + 1 print(a) s = su() #执行这段代码会报错(如果只是调用不修改是不会报错的) 更改为: #!/usr/bin/env python a = 100def su(): global a a = a + 1 print(a) s = su() 总结: 在python的函数中和全局同名的变量,如果修改变量的值就会变成局部变

C语言中的函数、数组与指针

1.函数:当程序很小的时候,我们可以使用一个main函数就能搞定,但当程序变大的时候,就超出了人的大脑承受范围,逻辑不清了,这时候就需要把一个大程序分成许多小的模块来组织,于是就出现了函数概念:  函数是C语言代码的基本组成部分,它是一个小的模块,整个程序由很多个功能独立的模块(函数)组成.这就是程序设计的基本分化方法: (1) 写一个函数的关键: 函数定义:函数的定义是这个函数的实现,函数定义中包含了函数体,函数体中的代码段决定了这个函数的功能: 函数声明:函数声明也称函数原型声明,函数的原型

C++中虚函数

本文为博主学习虚函数时,结合网上博客和相关书籍所写.主要分为两部分:虚函数的定义要遵循的规则,虚函数表. 一.虚函数的定义要遵循的规则 1.如果虚函数在基类与派生类中出现,仅仅是名字相同,而形式参数不同,或者是返回类型不同,那么即使加上了virtual关键字,也是不会进行滞后联编的. 解读:派生类中根据需要对虚函数进行重定义是,格式要求有三点: (1)与基类的虚函数有相同的参数个数: (2)与基类的虚函数有相同的参数类型: (3)与基类的虚函数有相同的返回类型:或者与基类虚函数的相同,或者都返回

常函数

为避免成员函数修改成员变量,则可将成员函数定义为常函数.格式如下. void function_name ( void )const {} 若成员变量是mutable 关键字(去常const_cast)修饰的,则在函数中允许更改 常对象调用常函数,非常对象调用非常函数.常函数与非常函数可重载(this指针类型不同). 若无非常变量,则非常对象可以调用常函数:但常对象不可调用非常函数 #include "stdafx.h" #include <iostream> using

&lt;C++&gt; 类(3):初始化列表 常函数和常量对象 虚函数与多态(包括纯虚函数)

一.初始化列表(初始化列表中必须有的两个内容) 1.类中const的成员变量: ①特点:不能修改 必须初始化 在构造函数后面加冒号 格式为:":变量名(值)" 也就是说 常量必须在初始化列表中初始化 ②执行顺序:构造函数先执行初始化列表 然后执行函数中的内容 1 #include<iostream> 2 using namespace std; 3 4 class CPerson 5 { 6 public: 7 const int a; 8 public: 9 CPerso

c++ 动态判断基类指针指向的子类类型(typeid)

我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 本文提供了两种方法 (1) 自定义类id, (2)typeid 一.自定义id 如下所示基类father有两个子类son1 和 son2,我们在基类中定义类虚函数id,子类中分别重载了该函数,各个子类返回值都不同 1 class father 2 { 3 public: 4 virtual void fun() 5 {

const指针和指向const的指针

int *const p=&a; 这是const指针,这种指针必须在定义时就给出它所指向的地址,否则会error:uninitialized const 'p'.const指针的指针本身是const类型,所以不能修改它所指向的地址,但可以修改它所指向的值. const int *p; 这是指向const对象的指针,可以修改指向的地址,但不能通过这种指针来修改它所指向的值,即使它所指向的值不是const类型的. const int *const p=&a; 这是指向const类型的const

c++中函数中变量内存分配以及返回指针、引用类型的思考

众所周知,我们在编程的时候经常会在函数中声明局部变量(包括普通类型的变量.指针.引用等等). 同时,为了满足程序功能的需要,函数的返回值也经常是指针类型或是引用类型,而这返回的指针或是引用也经常指向函数中我们自己声明的局部变量. 这样,程序在某些情况下就可能存在一定的问题.看似很简单的问题,通过仔细的分析,我们就能够更好的理解c++中内存分配和释放的问题. 好,废话不多说,我们进入正题.首先,简单介绍一下程序的内存区域的分配: 程序的内存分配 ①堆区(heap).这一部分主要是由程序开发人员自己

C++中使用函数指针 【瓦特芯笔记】

     在C++类中使用函数指针. 类型定义:      typedef 返回类型(类名::*新类型)(参数表) //类定义 class CA { public: char lcFun(int a) { return; } };      CA ca;      typedef char (CA::*PTRFUN)(int);      PTRFUN pFun;     void main()     {        pFun = CA::lcFun;        ca.(*pFun)(2