0

Наиболее раздражающая ошибка разбора: конструктор без аргументов

11

Я компилировал программу на C++ в Cygwin с использованием g++ и у меня был класс, у которого конструктор не имел аргументов. У меня были следующие строки кода:

MyClass myObj();
myObj.function1();

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

error: request for member 'function1' in 'myObj', which is of non-class type 'MyClass ()()'

После небольшого исследования я узнал, что решение проблемы состоит в том, чтобы изменить первую строку на:

MyClass myObj;

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

5 ответ(ов)

0

Хотя выражение MyClass myObj(); может быть интерпретировано как определение объекта с пустым инициализатором или как объявление функции, стандарт языка предписывает разрешать эту неоднозначность в пользу объявления функции. Пустой инициализации в виде круглых скобок разрешена в других контекстах, например, в выражении new или при создании временного объекта, инициализированного значением.

0

В стандарте C++ (§8.5.8) указано следующее:

Объекты, инициализируемые пустым набором круглых скобок, т.е. (), должны быть инициализированы по значению.

[Примечание: поскольку () не допускается синтаксисом для инициализаторов,

X a ();

это не объявление объекта класса X, а объявление функции, которая не принимает аргументов и возвращает объект типа X. Форма () разрешена в некоторых других контекстах инициализации (5.3.4, 5.2.3, 12.6.2). —конец примечания ]

Таким образом, имея X a();, вы фактически создаете объявление функции, а не объекта. Если же вы хотите инициализировать объект, вам нужно использовать другой синтаксис, например, X a; или X a{};, чтобы создать объект класса X.

0

Конструкция MyClass myObj(); интерпретируется компилятором как объявление функции, которая называется myObj, не принимает аргументов и возвращает объект типа MyClass. Такое поведение является стандартным в C++. Возможно, вы никогда не видели компиляторов, принимающих такую запись, скорее всего, это связано с тем, что она часто вызывает недоразумения.

С другой стороны, конструкция MyClass* myPtr = new MyClass(); является корректной. Здесь мы создаем указатель myPtr, который указывает на новый объект типа MyClass, и это может быть причиной вашего недоразумения. Чтобы создать объект MyClass на стеке, вы можете использовать следующую запись: MyClass myObj;.

0

Ваш код заставляет компилятор думать, что вы объявляете функцию с именем myObj, которая не принимает аргументов и возвращает MyClass. Это неопределенность действительно может быть раздражающей.

0

Стандарт не требует использования круглых скобок.

int* x = new int;

— это корректный синтаксис.

В вашем случае myclass myobj(); является прототипом функции. В то время как myclass myobj; — это объявление переменной.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь