Предположим, у нас есть класс без конструктора по умолчанию:
class Foo {
public:
Foo(int data) : _data(data) { }
int data(void) const { return _data; }
private:
int _data;
};
Почему эта компиляция и что она делает:
Foo x();
Даже если скомпилировано выше, вы можете 'сделать любое из следующего:
x.data(); // doesn't compile: request for member 'data' in 'x', which is of non-class type 'Foo()'
x->data(); // doesn't compile: request for member 'data' in 'x', which is of non-class type 'Foo()'
x().data(); // compiles!!! but linking fails with: undefined reference to `x()'
x()->data();// doesn't compile: base operand of '->' has non-pointer type 'Foo'
Я думаю, я просто запутался в том, что добавление () после x делает, и почему язык это позволяет?Это все допустимо и / или полезно?Кажется, что ни один экземпляр Foo не выделяется в стеке, потому что даже с -Wunused-variable не появляется предупреждение о x в Foo x();
В противоположность этому оба следующих компонента не компилируются:
Foo *x = new Foo; // error: no matching function for call to 'Foo::Foo()
Foo *y = new Foo();// error: no matching function for call to 'Foo::Foo()
Это кажется более последовательным, я не понимаю, что происходит с Foo x();
РЕДАКТИРОВАТЬ: Хорошо, разобрался.Foo x()
;является прототипом функции 'x', которая не принимает параметров и возвращает Foo.Поскольку функция нигде не определена, попытка использовать ее как экземпляр Foo (x.data()
) или указатель Foo (x->data()
) не работает.x()->data()
не работает, потому что x()
имеет тип Foo
, а не указатель на Foo
.x().data()
компилируется, потому что x()
возвращает Foo
, у которого есть метод data
, но он не может соединиться, потому что функция x
не была определена.Уф.