Использование конструктора в вызове функции? - PullRequest
8 голосов
/ 10 марта 2011

Некоторое время я искал хорошее объяснение, почему / почему следующее использование конструктора struct в качестве аргумента функции недопустимо. Может кто-нибудь предоставить один?

// Begin simple illustrative example C++ program    
#include<vector.h>

struct Item  
{  
  Item(double data, const int lead)
  : m_grid(data), m_lead(lead) {}

  double m_grid;
  int m_lead;
};

int main()
{
  double img = 0.0;
  int steps = 5;
  std::vector<Item> images;
  for (int i = 0; i < steps; i++)
  {
    img += 2.0;
    images.push_back(Item(img,i));
  }
  return 0;
}

У меня сложилось впечатление, что у конструктора нет ни типа возврата, ни оператора ...

Ответы [ 4 ]

8 голосов
/ 10 марта 2011

Это не конструктор или его возвращаемое значение, которое передается в push_back.C ++ фактически использует конструктор для создания безымянного временного объекта, который существует только на время вызова функции;как правило, в стеке.Затем это передается push_back, и push_back копирует его содержимое в ваш вектор.

6 голосов
/ 10 марта 2011

Это законно.

Вы никогда не вызываете конструктор самостоятельно; вы на самом деле просто объявляете безымянный или «временный» объект типа Item. Посмотрите, как развивается синтаксис, когда вы делаете объект безымянным:

Item a(img,i); // normal
Item(img,i);   // temporary

Даже если выглядит так, как будто вы вызываете конструктор как функцию, это не так.

В любом случае, вы можете использовать временное значение как «значение» (потому что оно одно) в аргументах функций и т. П., Что вы и делаете здесь.


Кстати, не используйте старые заголовки iostream.h и vector.h. Они датируются 1998 годом. В стандарте ISO C ++ вы должны использовать iostream и vector соответственно. Стандартные заголовки в C ++ не заканчиваются на «.h» (inb4, игнорируя заголовки C, унаследованные для обратной совместимости).

4 голосов
/ 10 марта 2011

Это допустимо, потому что push_back принимает свой аргумент по ссылке const, а затем создает копию объекта. Вызов конструктора создает временный объект, который является значением. Ссылка на констант может связать значение. Метод не может изменить переданный объект, но он может создать копию.

3 голосов
/ 10 марта 2011

Хотя это выглядит как вызов функции, выражение Item (img, i) фактически является созданием временного объекта. Разница в том, что во время выполнения память будет выделена для объекта в стеке, а затем будет вызван конструктор, тогда как если бы это был обычный вызов функции, память не была бы выделена.

...