Контейнеры STL со ссылкой на объекты
20321 просмотра
5 ответа
Я знаю, что контейнеры STL копируют объекты. Так скажи, у меня есть
list<SampleClass> l;
каждый раз, когда я делаю
SampleClass t(...);
l.push_back(t);
копия т будет сделана. Если SampleClass большой, то это будет очень дорого.
Но если я объявлю l контейнером ссылок,
list<SampleClass&> l;
Когда я делаю
l.push_back(t);
Будет ли это избегать копирования объектов?
Автор: Vendetta Источник Размещён: 12.11.2019 09:46Ответы (5)
20 плюса
К сожалению, нет, он не скомпилируется (по крайней мере, с 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));
Shared острие несет некоторые дополнительные издержки, но это минимально.
Автор: Dave Branton Размещён: 10.10.2011 02:0732 плюса
Если вы знаете, что делаете, вы можете создать вектор ссылок, используя 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 };
}
Заметьте, конечно, что все это рухнет на вас, если какая-либо из упомянутых переменных выйдет из области видимости, пока вы все еще держите ссылки на них.
Автор: Kerrek SB Размещён: 10.10.2011 02:164 плюса
Контейнеры стандартной библиотеки требуют, чтобы их типы были копируемыми; поскольку ссылки не являются, вы не можете хранить их в контейнерах для начала. Вы можете хранить указатели, если вы осторожны с временем жизни объекта. Boost имеет несколько контейнеров указателей, чтобы помочь с этим, или у вас есть умные указатели. Тем не менее, обратите внимание, что auto_ptr
это не копируется (поскольку стандарт определяет это для этой цели), поэтому shared_ptr
и unique_ptr
ваши лучшие ставки сейчас. Оба являются стандартными в C ++ 11, а первый поддерживается через boost в C ++ 03.
1 плюс
0 плюса
Теперь, когда у вас есть умный указатель, вы можете использовать его для управления памятью и извлекать из них необработанные указатели для использования в контейнерах STL. Таким образом вы сохраняете право собственности на контейнер.
Здесь у меня есть unique_ptr дерева, но я использовал стек STL для хранения необработанных указателей
void TreeTraversal(unique_ptr<BinaryTreeNode>& root) {
stack<BinaryTreeNode *> _stack;
BinaryTreeNode *p = root.get();
_stack.push(p);
while(!_stack.empty()) {
p = _stack.top();
_stack.pop();
...
_stack.push(p->left);
_stack.push(p->right);
}
}
int main() {
unique_ptr<BinaryTreeNode> root = unique_ptr<BinaryTreeNode>(new BinaryTreeNode(...));
TreeTraversal(root);
}
Автор: saha
Размещён: 13.01.2018 06:59
Вопросы из категории :
- c++ What are the barriers to understanding pointers and what can be done to overcome them?
- c++ Какой самый простой способ для анализа файла INI в C ++?
- c++ Когда вы должны использовать «друг» в C ++?
- c++ Как вы очищаете переменную stringstream?
- c++ В C ++ конструктор и деструктор могут быть встроенными функциями?
- stl Зачем использовать итераторы вместо индексов массива?
- stl Инициализация статического std :: map <int, int> в C ++
- stl К STL или! STL, вот в чем вопрос
- stl Строка c_str () против данных ()
- stl Объединение двух стандартных: векторов
- reference Каковы различия между переменной-указателем и ссылочной переменной в C ++?
- reference Есть ли разница между "==" и "есть"?
- reference Определение манифеста обнаруженной сборки не соответствует ссылке на сборку
- reference Есть ли ошибки, использующие varargs с опорными параметрами
- reference Рекомендации для хорошего справочника vi?
- pass-by-reference Передать по ссылке или передать по значению?
- pass-by-reference Является ли Java «передачей по ссылке» или «передачей по значению»?
- pass-by-reference Зачем использовать ключевое слово ref при передаче объекта?
- pass-by-reference В чем разница между передачей по ссылке или передачей по значению?
- pass-by-reference Является ли JavaScript языком передачи по ссылке или передачей по значению?