Почему определение переменной ClassName ClassName в C ++ компилируется и работает правильно?
-
06-07-2019 - |
Вопрос
Скажем, у меня есть определение класса:
class CustomClass {
int member;
};
Почему следующее определение переменной компилируется и работает правильно:
CustomClass CustomClass; // the variable is properly constructed
Разве это не должно сбивать с толку компилятор и приводить к тому, что он указывает на ошибку?
Решение
Имена классов и имена переменных занимают два отдельных пространства имен. Компилятор может выяснить, что первый CustomClass
является типом, а второй CustomClass
является именем переменной.
Другие советы
Запрашиваемое сомнение не обязательно касается чувствительного к регистру режима C ++, это объявление переменной, имя которой совпадает с именем класса, определенного выше. Я думаю, что ваш компилятор c ++ достаточно умен, чтобы определить тип токена, который он анализирует.
Я думаю, что магия компилятора заставляет его работать. Я согласен с вами, что в идеале это должна быть ошибка компилятора (по крайней мере, меня смущает).
Если вы попробуете что-то вроде
#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 ++ достаточно сложностей, чтобы взволновать программистов, как насчет того, чтобы компиляторы тоже внесли свой вклад :-)?
Это В ответе косвенно указана основная причина, по которой это возможно в C ++. Это сводится к обратной совместимости с C. В типах C было другое пространство имен, поэтому было возможно объявить тип и объект или тип и функцию с тем же именем.
Для совместимости с C в C ++ добавлены некоторые специальные правила, позволяющие объекту или функции скрывать объявление типа.
Конечно, почему нет? Теперь, как снова определить класс CustomClass? Легко: используйте ключевое слово " class " ;, например: учебный класс ; класс CustomClass CustomClassAgain;