假设你想获取成员函数size()的地址,那么你会这样写:
auto address = &demo::size;
但它也很可能是成员数据size 的地址。模棱两可的情况。因此,语言规范不允许这样做。
这并不是说 C++ 委员会不可能提出解决方案,但我认为这样做并没有什么重大收获。因此,为了简单起见,标准只是不允许这样做。
此外,如果将成员函数 size() 声明为:
typedef void fun_type();
struct demo
{
fun_type size; //It looks like a member-data, but it's a member-function
};
void demo::size() //define the member function
{
std::cout << "It is crazy!" << std::endl;
}
int main()
{
demo d;
d.size(); //call the function!
}
输出:
太疯狂了!
查看在线演示:http://ideone.com/ZjwyJ
现在如果我们可以实现上面解释的成员函数,那么即使肉眼也很明显你不能添加另一个具有 same 名称的成员:
struct demo
{
fun_type size;
int size; //error - choose a different name for the member!
};
等等,这并不完全正确,因为故事还没有结束。我需要在这里添加一些不太明显的东西。您可以添加多个同名的成员:
typedef void fun_type0();
typedef void fun_type1(int a);
typedef void fun_type2(int a, int b);
struct demo
{
fun_type0 member; //ok
fun_type1 member; //ok
fun_type2 member; //ok
};
这是完全有效的代码,因为每个成员都是不同类型的函数,因此您可以将它们定义为:
void demo::member()
{
std::cout << "member()" << std::endl;
}
void demo::member(int a)
{
std::cout << "member(" << a << ")" << std::endl;
}
void demo::member(int a, int b)
{
std::cout << "member(" << a << ", "<< b << ")" << std::endl;
}
测试代码:
int main()
{
demo d;
d.member();
d.member(10);
d.member(200,300);
}
输出:
member()
member(10)
member(200, 300)
在线演示:http://ideone.com/OM97Q
结论...
您可以添加具有相同名称的成员,只要它们是不同类型的函数。这是由一个名为member-function-overloading(或简单的函数重载)1 的功能启用的。
1.不幸的是,该语言没有为成员数据提供类似的功能,例如成员数据重载,该语言也不提供跨成员重载(允许成员数据和成员函数具有相同的名称 - 案例在问题中)。
那么这里自然会产生一个问题:它们不会导致歧义问题吗?是的,他们有。但需要注意的一点是,C++ 委员会提出了一个解决这个歧义问题的解决方案,因为他们看到了这样做的巨大收益(在函数重载的情况下)。
但是问题中的情况仍然模棱两可,因为委员会没有提出解决方案,因为他们没有看到这样做有任何巨大的优势(如前所述)。另外,当我说“C++ 委员会提出了解决方案” 时,我并不是说 解决方案 已经标准化,我只是说他们知道编译器如何解决它,以及解决方案有多复杂。