常量对象 只能调用 常成员函数

一、遇到问题:

//函数声明

void ReadRanFile(CString szFilePath);

const CFvArray<CString>& GetPanelGrade() const { return m_fvArrayPanelGrade; }

//在另一个文件中调用ReadtRanFile这个函数

const CFsJudConfig& psJudConfig = m_pFsDefJudge->GetJudConfig();

psJudgeConfig.ReadRanFile(szFilePath); //报错!!

报错内容:cannot convert 'this' pointer from 'constCFsJudConfig' to 'CFsJudConfig&'

这就是因为:使用常量对象CFsJudConfig 调用了 非常量函数ReadRanFile()!

解决方法:

1.将普通成员函数 改为 常量成员函数

void ReadRanFile(CString szFilePath);=》void ReadRanFile(CString szFilePath) const;

(注意:1.1 此时,常量函数内部。常成员函数不能 "更新/修改"类的成员变量,也不能调用该类中没有用const修饰的成员函数,只能调用常成员函数!

1.2 这个const函数是只读的,不可修改,而非const成员函数是可读可写的。)

2.重载一个GetJudConfig()方法

CFsJudConfig GetJudConfig() { return m_pFsDefJudge; }//const关键字可以用于对重载函数的区分

二、原因分析

参考:常量对象只能调用常成员函数 原因分析_牛客博客

1. 首先我们需要知道const *p(常量指针)类型无法转换到*p类型(普通指针),但*p能够向const *p转换

|-------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include<iostream> using namespace std; void const_fun( ``const int``* a) { ``cout << ``"const fun" << endl; } void fun(``int *a) { ``cout << ``"fun" << endl; } int main() { ``int *a=nullptr; ``const_fun(a); ``const int *b = nullptr; ``fun(b); ``//*b为常量指针 无法转换为普通指针 报错 } |

2. 于是我们还可以通过const来进行函数重载,使const p与p调用不同的函数

|----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include<iostream> using namespace std; void fun( ``const int``* a) { ``cout << ``"const fun" << endl; } void fun(``int *a) { ``cout << ``"fun" << endl; } int main() { ``int *a=nullptr; ``fun(a); ``const int *b = nullptr; ``fun(b); } |

输出

fun

const fun

3. 与类对比

我们都知道类中函数都隐式传入了this指针,而常函数的作用就是修饰*this不能被修改

也就是 type fun(class *this) const就相当于type fun(const class *this)

于是类中就能存在type fun()与type fun() const两个函数,也就是重载了fun函数

常量对象传入函数的是const指针,普通对象传入的为普通指针。

而普通指针能向常量指针转换而常量指针无法向普通指针转换。

故普通成员能调用常函数,而常量成员无法调用普通函数。

|----------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include<iostream> using namespace std; class A{ public``: ``void fun() ``const //相当于 void fun(const A *this) ``{ ``cout << ``"fun const" << endl; ``} ``void fun() ``//相当于 void fun(A *this) ``{ ``cout << ``"fun" << endl; ``} ``void test() ``{ ``} ``void test2() ``const ``{ ``} }; int main() { ``const A a; ``A b; ``a.fun(); ``b.fun(); ``//a.test(); //报错 常成员不能调用普通函数 ``b.test(); a.test2(); b.test2(); //"普通"成员能调用const成员函数 因为普通指针能转换为常量指针 } |

结果

fun const

fun

总结

  1. 我们可以通过常量指针与普通指针来重载函数
  2. 由于常量指针不能向普通指针转换,因此我们不能向参数为普通指针的函数传入常量指针。故我们不能通过const对象调用普通成员函数。
  3. 普通指针能转换为常量指针。故普通对象能调用普通函数也能调用常函数
相关推荐
longlongzihan13 分钟前
LeetCode 5. 最长回文子串:从暴力匹配到中心扩展的思维演进
c++·算法·leetcode
多弗朗皮卡丘25 分钟前
C++继承
c++·继承
geovindu33 分钟前
rust: Abstract Factory pattern
开发语言·后端·设计模式·rust·抽象工厂模式
“AI国潮设计-小江”36 分钟前
《Python+SDXL实战:用ControlNet批量生成“英歌舞麻将糕”IP,附自动化脚本与商用思路》
开发语言·人工智能·python·prompt·aigc
Cc.Y1 小时前
Java零基础入门:封装与继承 —— 从“裸奔“到“穿衣服“,从“重复造轮子“到“站在巨人肩膀上“
java·开发语言
Escalating_xu1 小时前
【C 语言】深入理解指针(4):回调函数、qsort、void * 与泛型排序的模拟实现
java·c语言·开发语言
汉克老师1 小时前
GESP2026年9月认证C++七级( 第三部分编程题(2、括号序列))精讲
c++·gesp·小学生·学c++编程
吠品1 小时前
GitHub 周榜拆解:决策小模型扎堆上位
c语言·开发语言·算法
见叶之秋2 小时前
C++ 泛型世界的两块拼图:容器适配器与仿函数
java·开发语言
逗脑IDE2 小时前
零基础学ESP32:RFID无线射频卡——让ESP32拥有“刷卡“能力!
开发语言·网络·人工智能·python·esp32·硬件开发