类方法和同名变量,在 C++ 中编译错误而不是在 Java 中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/467815/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:00:32  来源:igfitidea点击:

Class method and variable with same name, compile error in C++ not in Java?

javac++

提问by kal

class Test {

      bool isVal() const {
          return isVal;
      }

  private:

      bool isVal;
};

On Compiling this file it says

在编译这个文件时,它说

testClass.cpp:9: declaration of `bool Test::isVal'

testClass.cpp:3: conflicts with previous declaration `bool Test::isVal()'

testClass.cpp:9:`bool Test::isVal' 的声明

testClass.cpp:3:与之前的声明‘bool Test::isVal()’冲突

Although the same would work for java

虽然同样适用于java

class Test {

  private boolean isVal;

  public boolean isVal() {
      return isVal;
  }

}

Why does the compile error occur in C++ not in Java?

为什么编译错误发生在 C++ 中而不是 Java 中?

采纳答案by Johannes Schaub - litb

Because C++ is not Java. You can take the address of a member:

因为 C++ 不是 Java。您可以获取成员的地址:

&Test::isVal

So you can't have two members have the same name, except that you can overload member functions. Even if you could disambiguate that by some kind of cast, the next problem would already arise at other places.

所以你不能有两个同名的成员,除非你可以重载成员函数。即使您可以通过某种类型的演员表消除歧义,下一个问题也会在其他地方出现。

In C++, a lot of people including me usually call data members specially, like putting a mbefore their name. This avoids the problem:

在C++中,包括我在内的很多人通常都会专门称呼数据成员,比如m在他们的名字前加一个。这样就避免了这个问题:

class Test {
public:
    bool IsVal() const { return mIsVal; }
private:
    bool mIsVal;
};

回答by Kevin Loney

Functions in c/c++ are just pointers to a location in memory where the code is located, isVal (as a boolean) and isVal (as a function) are therefore ambiguous.

c/c++ 中的函数只是指向代码所在内存位置的指针,因此 isVal(作为布尔值)和 isVal(作为函数)是不明确的。

回答by Charlie Martin

The quick answer is "because that's the way C++ works." C++ doesn't have a separate name space for member variables and member functions (ie, "methods") where Java (apparently, as I haven't tried this) does.

快速回答是“因为这就是 C++ 的工作方式”。C++ 没有为成员变量和成员函数(即“方法”)提供单独的命名空间,而 Java(显然,因为我还没有尝试过)有。

In any case, remember the old story about the guy who went to a doctor and said "Doc, it hurts when I do this." To which the doctor replied "well, don't dothat!" This is a language peculiarity on its way to becoming a Dumb Programmer Trick.

在任何情况下,请记住是谁去看医生,说那家伙老故事“医生,我这样做时,它会伤害这个。” 医生回答说:“好吧,不要那样!” 这是成为愚蠢程序员技巧的一种语言特性。

回答by hongcc

If you have some reason to use same names for variable and method (maybe reduce naming for things have almost same purpose,etc??), I suggest that just naming them with different case:

如果您有理由为变量和方法使用相同的名称(也许可以减少对几乎相同目的的命名等?),我建议只用不同的大小写命名它们:

class Test 
{
    private bool isVal;
    public bool ISVAL() 
    {   return isVal;  }
}

回答by hongcc

C++ applies name mangling to function names and global variables. Local variables are not mangled. The problem arises because in C you can access the address of a variable or a function (thus in C++ as well) e.g. :

C++ 将名称修改应用于函数名称和全局变量。局部变量不会被破坏。出现问题是因为在 C 中您可以访问变量或函数的地址(因此在 C++ 中也是如此),例如:

struct noob{
    bool noobvar;
    void noobvar(){};
};

One can say, why not apply name mangling to local variables as well and then have an internal local representation such as

可以说,为什么不将名称修改也应用于局部变量,然后具有内部局部表示,例如

bool __noobvar_avar;
void __noobvar_void_fun;

and suppose that they receive the addresses during execution 0x000A and 0x00C0 respectively.

并假设它们在执行期间分别收到地址 0x000A 和 0x00C0。

However if we write somewhere in the code:

但是,如果我们在代码中的某处写:

&noob::noobvar

What should the program do ?

程序应该做什么?

  1. return the address of the variable noobvar , i.e. 0x000A
  2. return the addres of the noobvar function , i.e. 0x00C0
  1. 返回变量 noobvar 的地址,即 0x000A
  2. 返回 noobvar 函数的地址,即 0x00C0

You can see that since in C , and therefore in C++ , you can issue an "address of", it is not legal to have variables and functions with the same name within the same scope of resolution.

您可以看到,由于在 C 中,因此在 C++ 中,您可以发出“地址”,因此在同一解析范围内具有相同名称的变量和函数是不合法的。

回答by R Sahu

The following section from the C++ Draft Standard N3337 specifies when a name can be overloaded.

C++ 草案标准 N3337 中的以下部分指定了何时可以重载名称。

13 Overloading

1 When two or more different declarations are specified for a single name in the same scope, that name is said to be overloaded. By extension, two declarations in the same scope that declare the same name but with different types are called overloaded declarations. Only function and function template declarations can be overloaded; variable and type declarations cannot be overloaded.

13 重载

1 当在同一范围内为单个名称指定了两个或多个不同的声明时,该名称被称为重载。通过扩展,同一作用域中声明相同名称但具有不同类型的两个声明称为重载声明。只能重载函数和函数模板声明;变量和类型声明不能重载。

When you define a class as:

当您将类定义为:

class Test {

      bool isVal() const {
          return isVal;
      }

  private:

      bool isVal;
};

you are overloading the name isValwithin the scope of the class. Such an overload is allowed only when isValis a member function. It is not allowed when isValis a member variable.

您正在isVal类范围内重载名称。只有当isVal是成员函数时才允许这种重载。当isVal是成员变量时是不允许的。