Метод класса и переменная с тем же именем, ошибка компиляции в C ++, а не в Java? - PullRequest
34 голосов
/ 22 января 2009
class Test {

      bool isVal() const {
          return isVal;
      }

  private:

      bool isVal;
};

При компиляции этого файла написано

testClass.cpp: 9: объявление `bool Test :: isVal '

testClass.cpp: 3: конфликтует с предыдущее объявление `bool Test :: isVal ()

Хотя то же самое будет работать для Java

class Test {

  private boolean isVal;

  public boolean isVal() {
      return isVal;
  }

}

Почему ошибка компиляции происходит в C ++, а не в Java?

Ответы [ 6 ]

65 голосов
/ 22 января 2009

Потому что C ++ - это не Java. Вы можете взять адрес участника:

&Test::isVal

Таким образом, вы не можете иметь два члена с одинаковыми именами, за исключением того, что вы можете перегружать функции-члены. Даже если бы вы могли устранить это неоднозначно, следующая проблема уже возникла бы в других местах.

В C ++ многие люди, включая меня, обычно называют члены данных специально, например, ставят m перед своим именем. Это позволяет избежать проблемы:

class Test {
public:
    bool IsVal() const { return mIsVal; }
private:
    bool mIsVal;
};
11 голосов
/ 23 февраля 2012

C ++ применяет искажение имен к именам функций и глобальным переменным. Локальные переменные не искажены. Проблема возникает потому, что в C вы можете получить доступ к адресу переменной или функции (например, в C ++), например. :

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

Можно сказать, почему бы не применить искажение имен к локальным переменным, а затем иметь внутреннее локальное представление, такое как

bool __noobvar_avar;
void __noobvar_void_fun;

и предположим, что они получают адреса во время выполнения 0x000A и 0x00C0 соответственно.

Однако, если мы напишем где-нибудь в коде:

&noob::noobvar

Что должна делать программа?

  1. возвращает адрес переменной noobvar, то есть 0x000A
  2. возвращает адреса функции noobvar, то есть 0x00C0

Вы можете видеть, что, поскольку в C и, следовательно, в C ++ вы можете выдавать «адрес», недопустимо иметь переменные и функции с одинаковыми именами в одной и той же области разрешения.

8 голосов
/ 22 января 2009

Функции в c / c ++ - это просто указатели на место в памяти, где находится код, поэтому isVal (как логическое значение) и isVal (как функция) поэтому неоднозначны.

5 голосов
/ 22 января 2009

Быстрый ответ - «потому что так работает C ++». В C ++ нет отдельного пространства имен для переменных-членов и функций-членов (т. Е. «Методов»), в которых Java (очевидно, как я не пробовал).

В любом случае, вспомните старую историю о парне, который пошел к врачу и сказал: «Док, мне больно, когда я делаю это ». На что доктор ответил "ну, не делай это!" Это языковая особенность на пути к превращению в тупого программиста.

3 голосов
/ 06 октября 2014

В следующем разделе проекта стандарта C ++ N3337 указывается, когда имя может быть перегружено.

13 Перегрузка

1 Если для одного имени в одной и той же области заданы два или более разных объявления, это имя называется перегруженным . Более того, два объявления в одной и той же области, которые объявляют одно и то же имя, но с разными типами, называются перегруженными объявлениями . Только объявления функций и шаблонов функций могут быть перегружены; объявления переменных и типов не могут быть перегружены.

Когда вы определяете класс как:

class Test {

      bool isVal() const {
          return isVal;
      }

  private:

      bool isVal;
};

вы перегружаете имя isVal в рамках класса. Такая перегрузка допускается только тогда, когда isVal является функцией-членом. Не допускается, когда isVal является переменной-членом.

0 голосов
/ 18 декабря 2011

Если у вас есть причины использовать одинаковые имена для переменных и методов (возможно, сократить именование для вещей, имеющих почти одинаковое назначение и т. Д. ??), я предлагаю просто присвоить им имена в другом регистре:

class Test 
{
    private bool isVal;
    public bool ISVAL() 
    {   return isVal;  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...