关于类成员函数重载的解析过程的非对称美

xiegaoqiang0413 2009-01-20 03:44:41
今天看了一上午成员函数重载解析过程,头都大了。至少在成员函数重载的解析过程上,我觉得没有一种对称美。不知道作者这么设计的原因是什么,请大家帮忙解释下。
代码是最好的例子!
1、
class SmallInt
{
public:
SmallInt(int iNumber=0):_iNumber(iNumber){}

static int Add(int a,int b){return a+b;}
float Add(float a,float b){return a+b;}
void PrintData()
{
cout<<"_iNumber:"<<_iNumber<<endl;
}
private:
int _iNumber;
};

int main()
{
float fVal=10.5;
SmallInt::Add(fVal,fVal); //出现错误
return 0;
}
上面的调用出现错误,原因是编译器在选择可行函数的时候把非静态和静态成员函数都选进去了。导致在第三阶段最佳匹配的时候匹配成float Add(float a,float b){return a+b;}。但是SmallInt::不能调用非静态成员函数。所以出错。

2、接下来在看const修饰符.
class SmallInt
{
public:
SmallInt(int iNumber=0):_iNumber(iNumber){}

static int Add(int a,int b){return a+b;}
float Add(float a,float b){return a+b;}
void PrintData()
{
cout<<"_iNumber:"<<_iNumber<<endl;
}
private:
int _iNumber;
};

int main()
{
float fVal=10.5;
const SmallInt si;
si.Add(fVal,fVal);//调用成功,调用的是static int Add(int a,int b){return a+b;}
return 0;
}

以上调用成功了,原因是编译器在第二阶段选择可行函数的时候,如果对象是const的,那么他只能调用const的成员函数(当然也包括静静态成员函数)而所有非const的成员函数都被排除了。所以可行函数其实只有一个static int Add(int a,int b){return a+b;},所以第三阶段的最佳匹配其实就是匹配这一个函数。

以上的疑惑:
对于SmallInt::调用来说,要到最佳匹配后才能决定这种调用格式对不对(有时候可能白选一场,因为即使你选出最佳匹配,但是调用格式不对,还是出错)。但是对于const对象来说,在第二阶段选择可行函数的时候就排除了非const成员。这样就不会存在上面提到的编译器做无用工。如果把静态函数的调用格式在第二阶段选择可行函数的时候就判断,不是更好吗?这样不是很对称吗?

请各位看客说说你们的看法
...全文
203 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
waizqfor 2009-01-20
  • 打赏
  • 举报
回复
UP了
iambic 2009-01-20
  • 打赏
  • 举报
回复
兄弟,你知道为什么权限控制要放在重载决议之后吗?就是防止你不小心弄错了。
如果你(小心或不小心的)把public改成private,或者把static改成non-static,程序的逻辑就完全变了。这时候编译器要是连屁都不放一个,干等最后程序员自己发现问题,不知道有多少脾气火暴的要狂骂C++是垃圾了。
编译器的目的不是为了让你的程序更容易的通过检查。
xiegaoqiang0413 2009-01-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hai040 的回复:]
问题是class::不一定就是调静态函数
比如派成类成员函数里调用基类函数
[/Quote]
既然在第三阶段能确定SmallInt::调用的是非静态成员,那就说明肯定就在第二阶段选择可行函数的时候就可以确定他是否调用的是非静态成员。如果这个时候就把非静态成员剔除。那么在第三阶段就可以匹配到函数,而不会出现错误。我觉得这样会合理一点。
iambic 2009-01-20
  • 打赏
  • 举报
回复
说白了,就是const/non-const参与重载(这是显然的),static/non-static不参与重载(不怎么显然,但也合情合理)。
chenzhp 2009-01-20
  • 打赏
  • 举报
回复
楼主确定编译器分阶段进行匹配?
hhyttppd 2009-01-20
  • 打赏
  • 举报
回复
我觉得因为C++可以用实例对象来访问静态函数,本身就会造成这种混淆(比如在类定义中),编译时不知道要调用的是静态成员函数还是实例成员函数,因为放在第三阶段是合适的。

C#不允许使用类对象调用类的静态函数(对应于C++就是不允许 si.Add来调用静态函数),所以C#就不存在你说的问题。
hai040 2009-01-20
  • 打赏
  • 举报
回复
问题是class::不一定就是调静态函数
比如派成类成员函数里调用基类函数
taodm 2009-01-20
  • 打赏
  • 举报
回复
这个,哪个编译器有这么强的输出能力告诉你它是在哪个阶段砍重载的?介绍来,我下个玩玩。

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧