Каждый раз, когда вы помещаете объект в std :: vector, он должен сделать копию этого объекта.
Так что я могу просто наложить указатели вместо таких объектов?:
Class *ptr_Class;
Class object;
ptr_Class = &object;
std::vector<Class*> vector;
vector.push_back(ptr_Class);
Или по какой-то причине это не очень хорошая идея?
Используйте вектор интеллектуальных указателей. таким образом, вы не получите утечек памяти.
Метод, который вы описали, должен быть осторожным при появлении в списке, и вам нужно убедиться, что список пуст, когда вы закончили с ним.
Вы можете сделать вектор указателей, но вы должны знать, что вектор не будет автоматически вызывать delete
указателей, когда он будет сделан с ними. Если ваши указатели были выделены new
, вы должны delete
их самостоятельно, прежде чем удалять элементы или уничтожать вектор, или вы будете утечка памяти. Это сложно сделать, чтобы убедиться, что эта очистка происходит во всех случаях; в частности, исключения могут привести к тому, что код очистки в конце функции будет пропущен.
Безопаснее использовать вектор интеллектуальных указателей, который автоматически позаботится об этой очистке, даже перед исключениями. В С++ 11 вы можете просто создать вектор std::unique_ptr<T>
. С более старыми компиляторами, которые не поддерживают С++ 11, вы можете использовать std::tr1::shared_ptr<T>
или boost::shared_ptr<T>
, хотя это имеет некоторые накладные расходы из подсчета ссылок, которые вы не используете очень нужно. Вы не можете поместить С++ 98 std::auto_ptr
в вектор (поэтому он устарел и заменен на std::unique_ptr
в С++ 11).
Кроме того, в С++ 11 у вас есть некоторые опции для избежания копирования при вставке объекта в вектор:
myvector.push_back(std::move(myobject))
чтобы переместить объект в вектор, а не копировать его. Это все еще создает новый экземпляр внутри вектора, но он позволяет владеть любыми ресурсами, myobject
вместо их копирования. После этого myobject
не следует использовать, поскольку он больше не содержит данные, к которым он привык.myvector.emplace_back(...)
для создания нового объекта непосредственно в хранилище векторов. Это в основном оболочка для вашего конструктора классов, и ему может быть предоставлен любой набор аргументов, которые являются действительными для перехода к этому конструктору.Обратите внимание: если вы хотите, чтобы ваш вектор был полиморфным, то есть, если вы хотите иметь возможность хранить как квадраты, так и круги в векторе фигур, тогда ваш указатель хранения (предпочтительно интеллектуальные указатели) является вашим единственным вариантом. Все элементы, хранящиеся в векторе, должны быть одного типа, поэтому тип должен быть чем-то вроде указателя базового класса.
concept_t
в видео, DrawableConcept
в другой вашей ссылке. Все остальное - просто представить клиенту более приятный API.
Вы не используете "новое" или выделяете память, поэтому технически вы не будете иметь утечек памяти.
Однако вы должны быть осторожны с областью. Например, если у вас есть
std::vector<Class*> funcFoo()
{
Class *ptr_Class;
Class object;
ptr_Class = &object;
std::vector<Class*> vector;
vector.push_back(ptr_Class);
return vector;
}
вы получите вектор указателя, указывающего на объект в funcFoo. Этот объект, скорее всего, будет мусором после того, как вы покинете эту функцию.
Я предполагаю, что то, что вы хотите, больше похоже на это:
Class *ptr_Class = new Class();
std::vector<Class*> vector;
vector.push_back(ptr_Class);
Если это так, то вы должны помнить, чтобы освободить любую память, вы наделив new
путем вызова delete
.
Например:
for (unsigned int i = 0; i < vector.size(); ++i)
{
delete vector[i];
vector[i] = NULL;
}