繁体   English   中英

为什么类不能为函数和数据成员具有相同的名称?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM