类方法和具有相同名称的变量,C++中的编译错误不在Java中?

kal*_*kal 36 c++ java

class Test {

      bool isVal() const {
          return isVal;
      }

  private:

      bool isVal;
};
Run Code Online (Sandbox Code Playgroud)

在编译这个文件时,它说

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

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

虽然这同样适用于java

class Test {

  private boolean isVal;

  public boolean isVal() {
      return isVal;
  }

}
Run Code Online (Sandbox Code Playgroud)

不知道为什么C++无法解决这个问题.

Joh*_*itb 67

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

&Test::isVal
Run Code Online (Sandbox Code Playgroud)

所以你不能让两个成员具有相同的名称,除了你可以重载成员函数.即使你可以通过某种演员来消除歧义,下一个问题也会出现在其他地方.

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

class Test {
public:
    bool IsVal() const { return mIsVal; }
private:
    bool mIsVal;
};
Run Code Online (Sandbox Code Playgroud)

  • 在C++中,我们通常会特别调用成员变量,就像把am放在他们的名字之前???? 我们的确是?这是语言规范吗?这是一个完美的答案,直到那句话和它后面的例子. (24认同)
  • joe_mucchiello,出去统计所有流行的名称,例如"data_","_ data","mData","m_data"等等.我认为这证明我使用"通常"是合理的. (9认同)
  • @jmu"我不认为" - "因此它[名称重整]与问题无关".我不知道你的个人事务(你的意见)对我答案中任何事情的相关性有何客观影响?*我认为他们(我们!)因为姓名冲突的问题而做错了*我*把它放到我的问题中并认为它是相关的.您尚未提供相反声明的证据. (3认同)
  • ...而且,在幕后,这些函数实际上并没有真正使用相同的名称,因为它们通过类和参数签名来区分。 (2认同)
  • (IIRC) 微软首先做了 m_ 件事。我目前正在维护执行此操作的代码,但我不是粉丝。我可以接受私有数据成员的尾随下划线,但由于某种原因我不喜欢 m_ 前缀。 (2认同)
  • 我必须同意@jmucchiello。“我们通常”强烈暗示您是在代表所有人说话,而 C++ 社区中有很大一部分人_鄙视_这种令人憎恶的 `m` 前缀约定。 (2认同)
  • 伟大的。现在我应该抱怨有 getter 函数吗?:) (2认同)

小智 13

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

struct noob{
    bool noobvar;
    void noobvar(){};
};
Run Code Online (Sandbox Code Playgroud)

可以说,为什么不将名称修改应用于局部变量,然后有一个内部本地表示,如

bool __noobvar_avar;
void __noobvar_void_fun;
Run Code Online (Sandbox Code Playgroud)

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

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

&noob::noobvar
Run Code Online (Sandbox Code Playgroud)

该计划应该做什么?

  1. 返回变量noobvar的地址,即0x000A
  2. 返回noobvar函数的地址,即0x00C0

您可以看到,因为在C中,因此在C++中,您可以发出"地址",在相同的分辨率范围内使用具有相同名称的变量和函数是不合法的.


Kev*_*ney 9

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


Cha*_*tin 5

快速的答案是“因为这就是C ++的工作方式”。C ++没有用于成员变量和成员函数(即“方法”)的单独名称空间,而Java(显然,我还没有尝试过)可以这样做。

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


R S*_*ahu 5

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

13 超载

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

当您将类定义为:

class Test {

      bool isVal() const {
          return isVal;
      }

  private:

      bool isVal;
};
Run Code Online (Sandbox Code Playgroud)

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