Подтвердить что ты не робот

Контейнеры STL со ссылкой на объекты

Я знаю, что контейнеры STL копируют объекты. Так сказать, у меня есть

list<SampleClass> l;

каждый раз, когда я делаю

SampleClass t(...);
l.push_back(t);

будет сделана копия t. Если SampleClass большой, то это будет очень дорого.

Но если я объявляю l контейнером ссылок,

list<SampleClass&> l;

Когда я делаю

l.push_back(t);

Не будет ли копирование объектов?

4b9b3361

Ответ 1

К сожалению нет, он не будет компилироваться (по крайней мере, с stlport). Но альтернатива, которая заключается в том, чтобы хранить указатели на ваши объекты в контейнере, будет компилироваться отлично.

Это оставит вас немного лишнего синтаксического шума вокруг вашего кода - вам нужно будет что-то новое, чтобы вставить их в свой контейнер.

std::list<class_type*> l;
l.push_back(new class_type);

Однако, хотя объекты теперь не будут скопированы, они также не будут автоматически очищены для вас, когда список будет разрушен. Умные указатели решают это для вас, но ценой еще более синтаксического шума. И поскольку вы не можете поместить std:: auto_ptr в стандартные контейнеры, потому что они не могут быть скопированы, вы должны использовать их немного более тяжелые кузены повышения веса, общие указатели.

std::list<boost::shared_ptr<class_type> > l;
l.push_back(boost::shared_ptr<class_type>(new class_type));

Общие указатели несут некоторые дополнительные накладные расходы, но минимальны.

Ответ 2

Если вы знаете, что делаете, вы можете сделать вектор ссылок с помощью std::reference_wrapper:

#include <functional>
#include <vector>

int main()
{
  std::vector<std::reference_wrapper<int>> iv;

  int a = 12;
  iv.push_back(a);  // or std::ref(a)

  // now iv = { 12 };

  a = 13;

  // now iv = { 13 };
}

Обратите внимание, конечно, что любое из этого будет рушиться на вас, если какая-либо из упомянутых переменных выходит за пределы области действия, пока вы все еще держите ссылки на них.

Ответ 3

Стандартные библиотечные контейнеры требуют, чтобы их типы были гибкими; поскольку ссылок нет, вы не можете хранить их в контейнерах для начала. Вы можете хранить указатели, если вы будете осторожны в жизни объектов. У Boost есть некоторые контейнеры указателей, чтобы помочь с этим, или у вас есть интеллектуальные указатели. Обратите внимание, однако, что auto_ptr не поддается копированию (поскольку стандарт определяет его для этой цели), поэтому shared_ptr и unique_ptr - ваши лучшие ставки. Оба являются стандартными в С++ 11, а первые поддерживаются с помощью boost в С++ 03.

Ответ 4

Вам нужен контейнер указателей:

list<SampleClass*> l;