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

Seg*_*ult 29 c++ oop

为什么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()'
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 35

假设你想获取成员函数的地址size(),那么你会写这个:

auto address = &demo::size;
Run Code Online (Sandbox Code Playgroud)

但它也可能是成员数据的地址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!
}
Run Code Online (Sandbox Code Playgroud)

输出:

太疯狂了!

请参阅在线演示:http://ideone.com/ZjwyJ

现在,如果我们可以实现上面解释的成员函数,那么即使肉眼看到你也无法添加另一个同名的成员:

struct demo
{
    fun_type size;
    int      size; //error - choose a different name for the member!
};
Run Code Online (Sandbox Code Playgroud)

等等这不完全正确,因为故事尚未完成.我需要在这里添加一些不太明显的东西.您可以添加多个具有相同名称的成员:

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
};
Run Code Online (Sandbox Code Playgroud)

这是完全有效的代码,因为每个成员都是一个函数不同类型,所以你可以将它们定义为:

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;
}
Run Code Online (Sandbox Code Playgroud)

测试代码:

int main()
{
    demo d;
    d.member();
    d.member(10);
    d.member(200,300);
}
Run Code Online (Sandbox Code Playgroud)

输出:

member()
member(10)
member(200, 300)
Run Code Online (Sandbox Code Playgroud)

在线演示:http://ideone.com/OM97Q


结论...

您可以添加具有相同名称的成员,只要它们具有不同类型的功能即可.这使能由特征称为成员函数超载(或简单的函数超载)1.

1.不幸的是,该语言没有为成员数据提供类似的功能,比如成员数据重载,语言也没有提供跨成员重载(允许成员数据和成员函数具有相同的名称 - 问题中的情况).

所以这里有一个问题自然会出现:它们不会引起歧义问题吗?是的,他们这样做.但值得注意的是,C++委员会提出了一个解决这个模糊问题的解决方案,因为他们看到了这样做的巨大收获,(在函数重载的情况下).

但问题中的案例仍然含糊不清,因为委员会没有提出解决方案,因为他们没有看到这样做的任何巨大优势(如前所述).此外,当我说"C++委员会提出解决方案"时,我并不是说解决方案已经标准化,我只是意味着他们知道编译器如何解决它,以及解决方案有多复杂.


tho*_*mas 6

因为如果你size在某个地方使用你的类,那么编译器就不知道该怎么做了.它可以是int-data-member,也可以是函数指针.因此编译器无法分离这两种类型


Vin*_*enz 6

作为一个例子(不是最好的,但它可能在视觉上解释):

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;
}
Run Code Online (Sandbox Code Playgroud)

基本上变量也可以调用.所以编译器无法知道你的意图.当然,这是由语言定义的,它不可能与同一范围内的标识符具有相同的名称.