Разница в двух способах объявления экземпляра класса - PullRequest
2 голосов
/ 16 сентября 2011

Предположим, у нас есть класс без конструктора по умолчанию:

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 не была определена.Уф.

Ответы [ 2 ]

3 голосов
/ 16 сентября 2011
Foo x();

Это не создает объект x типа Foo. Вместо этого вы объявляете функцию x с типом возвращаемого значения Foo.

Эта C ++ FAQ запись должна быть полезной.

Теперь

Foo *x = new Foo;  //  error: no matching function for call to 'Foo::Foo()

new Foo вызывает конструктор по умолчанию, а у вас его нет и является причиной ошибки. Если класс предоставляет конструктор, то конструктор по умолчанию не предоставляется компилятором.

1 голос
/ 16 сентября 2011

Foo x(); - это не созданный по умолчанию объект типа Foo, а объявление функции: функция с именем x, не принимающая параметров и возвращающая Foo. Google для «Самый неприятный анализ».

Созданный по умолчанию объект типа Foo будет просто Foo x;.

...