Нет ли скобок в конструкторе без аргументов в качестве языка?
Я компилировал С++-программу в Cygwin, используя g++, и у меня был класс, у конструктора которого нет аргументов. У меня были строки:
MyClass myObj();
myObj.function1();
И при попытке скомпилировать его я получил сообщение:
error: запрос для члена 'function1' в 'myObj', который относится к классу non-class 'MyClass()()'
После небольшого исследования я обнаружил, что исправить было изменение этой первой строки на MyClass myObj;
Я мог бы поклясться, что раньше я делал пустые объявления конструкторов с круглыми скобками на С++. Возможно, это ограничение компилятора, который я использую, или действительно говорит о стандарте языка, не используйте круглые скобки для конструктора без аргументов?
Ответы
Ответ 1
Хотя MyClass myObj();
можно проанализировать как определение объекта с пустым инициализатором или объявлением функции, в стандарте языка указывается, что неоднозначность всегда разрешается в пользу объявления функции. Пустой инициализатор круглых скобок допускается в других контекстах, например. в выражении new
или при создании инициализированного значения.
Ответ 2
Это называется самой неприятной проблемой синтаксического анализа. Когда синтаксический анализатор видит
MyClass myObj();
Он думает, что вы объявляете функцию с именем myObj
, которая не имеет параметров и возвращает MyClass
.
Чтобы обойти это, используйте:
MyClass myObj;
Ответ 3
Я нашел это в стандарте С++ (§8.5.8):
Объект, инициализатор которого представляет собой пустой набор скобок, т.е.(), должен инициализироваться значением.
[Примечание: поскольку() не разрешено синтаксис инициализатора,
X a ();
не является объявлением объекта класса X, но объявление функции, не принимающей аргументом и возвратом X. Форма () разрешено в некоторых других контексты инициализации (5.3.4, 5.2.3, 12.6.2). -end note]
Ответ 4
Это довольно хорошо известная проблема и не зависит от компилятора. По существу, вы делали объявление функции, возвращающей тип MyObj. Неудивительно, что вы не можете вызвать его конструктор. См. С++ faq lite для хорошего объяснения
Ответ 5
Еще один наиболее неприятный-синтаксический хит. См. Например Функция сортировки не работает с объектным объектом, созданным в стеке?
Ответ 6
MyClass myObj();
Это анализируется как объявление функции, функция называется myObj, не принимает аргументов и возвращает объект MyClass. Я никогда не видел, чтобы компилятор это принимал. С другой стороны, MyClass* myPtr = new MyClass();
приемлемо, может быть, вы путаете?
Ответ 7
Ваша строка заставляет компилятор думать, что вы объявляете функцию с именем myObj
, которая не принимает аргументов и возвращает MyClass
. Это двусмысленное разрешение действительно раздражает.
Ответ 8
Стандарт не требует скобок.
int* x = new int;
является юридическим синтаксисом.
В вашем случае myclass myobj();
является прототипом функции. В то время как myclass myobj;
является переменной.