Почему определение переменной ClassName ClassName в C ++ компилируется и работает правильно? - PullRequest
2 голосов
/ 06 мая 2009

Скажите, у меня есть определение класса:

class CustomClass {
    int member;
};

Почему следующее определение переменной компилируется и работает правильно:

CustomClass CustomClass; // the variable is properly constructed

Разве это не должно сбивать с толку компилятор и вызывать ошибку?

Ответы [ 5 ]

10 голосов
/ 06 мая 2009

Имена классов и имена переменных занимают два отдельных пространства имен. Компилятор может выяснить, что первый CustomClass является типом, а второй CustomClass является именем переменной.

1 голос
/ 06 мая 2009

Запрашиваемое сомнение не обязательно касается чувствительного к регистру режима C ++, это объявление переменной, имя которой совпадает с именем класса, определенного выше. Я думаю, что ваш компилятор c ++ достаточно умен, чтобы определить тип токена, который он анализирует ..

0 голосов
/ 23 июня 2009

Конечно, а почему нет? Теперь, как снова определить класс CustomClass? Легко: используйте ключевое слово «класс», например: учебный класс ; класс CustomClass CustomClassAgain;

0 голосов
/ 06 мая 2009

В этом ответе косвенно указана основная причина, по которой это можно сделать в C ++. Все сводится к обратной совместимости с C. В типах C было другое пространство имен, поэтому можно было объявить тип и объект или тип и функцию с тем же именем.

Для совместимости с C в C ++ добавлены некоторые специальные правила, позволяющие объекту или функции скрывать объявление типа.

0 голосов
/ 06 мая 2009

Я думаю, его магия компилятора заставляет его работать. Я согласен с вами, что в идеале это должна быть ошибка компилятора (по крайней мере, меня смущает).

Если вы попробуете что-то вроде

#include <iostream>
class Test { public: int member; };
Test Test;   // comaeu warns 'expression has no effect!'
Test.member = 10; // dosen't compile!

int main(){
  Test Test;   
  Test.member = 10; // compiles fine after global 'Test's are commented!!
  std::cout<<Test.member<<std::endl;
  return 0;
}

Использование «Test.member» в глобальной области видимости не компилируется, но то же самое работает внутри «main ()» после того, как оба глобальных «Test» прокомментированы.

C ++ имеет достаточно сложностей, чтобы взволновать программистов, как насчет того, чтобы компиляторы тоже внесли свой вклад :-)?

...