[英]Why can't a class have same name for a function and a data member?
为什么c ++类不能为函数和数据成员使用相同的名称?
class demo{
public:
int size();
private:
int size;
};
int main(){
return 0;
}
C:\Users\S>g++ demo.c
demo.c:5:7: error: declaration of 'int demo::size'
demo.c:3:7: error: conflicts with previous declaration 'int demo::size()'
假设你想获取成员函数size()
的地址,那么你会写这个:
auto address = &demo::size;
但它也可能是成员数据size
的地址。 暧昧的情况。 因此,语言规范不允许这样做。
这并不是说C ++委员会不可能提出解决方案,但我认为这样做没有重大收获。 因此,标准只是禁止它,以保持简单。
此外,如果将成员函数size()
声明为:成员函数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
现在,如果我们可以实现上面解释的成员函数,那么即使肉眼看到你也无法添加另一个具有相同名称的成员:
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
结论...
您可以添加具有相同名称的成员,只要它们具有不同类型的功能即可。 这是通过一个功能调用成员函数超载 (或简单的函数超载)1 使能 。
1.不幸的是,该语言没有为成员数据提供类似的功能,比如成员数据重载,语言也不提供跨成员重载(允许成员数据和成员函数具有相同的名称 - 问题中的情况)。
所以这里有一个问题自然会出现:它们不会引起歧义问题吗? 是的,他们这样做。 但值得注意的是,C ++委员会提出了一个解决这个模糊问题的解决方案,因为他们看到了这样做的巨大收获,(在函数重载的情况下)。
但问题中的案例仍然含糊不清,因为委员会没有提出解决方案,因为他们没有看到这样做的任何巨大优势(如前所述)。 此外,当我说“C ++委员会提出解决方案”时 ,我并不是说解决方案已经标准化 ,我只是意味着他们知道编译器如何解决它,以及解决方案有多复杂。
因为如果你使用size
在你的类地方,那么编译器不知道该怎么办。 它可以是int-data-member,也可以是函数指针。 因此编译器无法分离这两种类型
作为一个例子(不是最好的,但它可能在视觉上解释):
class Size {
std::size_t size_;
public:
Size(std::size_t s = std::size_t() ) : size_(s){}
std::size_t operator()() const {
return size_;
}
void operator()(std::size_t s) {
size_ = s;
}
};
class Demo {
public:
Size size;
};
int main() {
Demo d;
d.size(10);
std::size_t size = d.size();
return 0;
}
基本上变量也可以调用。 所以编译器无法知道你的意图。 当然,这是由语言定义的,它不可能与同一范围内的标识符具有相同的名称。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.