一、遇到问题:
//函数声明
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
总结
- 我们可以通过常量指针与普通指针来重载函数
- 由于常量指针不能向普通指针转换,因此我们不能向参数为普通指针的函数传入常量指针。故我们不能通过const对象调用普通成员函数。
- 普通指针能转换为常量指针。故普通对象能调用普通函数也能调用常函数