Я программист на Objective-C и недавно запускаю C ++, и я наткнулся на вопрос об организации моего кода:
std::list<char *> stuff = std::list<char *>();
thing *object = new thing(stuff);
куда stuff
был бы предмет, который мне понадобился бы для жизни моего класса (то есть, пока он не будет разрушен), как избежать его потери?
На Objective-C я мог бы просто позвонить -retain
на конструкторе. На С ++?
Не используйте указатели, когда они вам не нужны, и не используйте сырые указатели (если у вас нет очень хорошая причина для них).
использование продолжительность автоматического хранения:
std::list<char> stuff;
thing object{stuff};
Конструктор thing
взял бы std::list<char>
в качестве аргумента:
#include <utility> // for std::move
class thing {
public:
explicit thing(std::list<char> stuff_) : stuff(std::move(stuff_)) {}
private:
std::list<char> stuff;
};
Если вы сделаете это таким образом, деструктор thing
будет называться, когда thing
выходит из области видимости, неявно вызывая деструктор stuff
, Много хорошие книги по С ++ объясните это очень подробно.
В отличие от Objective-C и C ++ использует RAII, а не подсчет ссылок. Основное правило: используйте автоматическую длительность хранения, когда это возможно, избегайте необработанных указателей владения и не используйте new
если у вас нет веских причин для этого.
Обычный способ будет копировать или перемещать stuff
в thing
в конструкторе thing
:
class thing {
public:
thing(std::list<char*> stuff) : stuff(std::move(stuff)) {}
private:
std::list<char *> stuff;
};
Не понятно, как вы собираетесь использовать stuff
в вашем примере, поэтому я собираюсь дать вам несколько разных вариантов.
thing
хранит свою собственную копию stuff
,
В этом случае ваш класс хранит объект типа std::list<char*>
,
class thing
{
public:
thing(std::list<char*>& aList):m_list(alist){}
std::list<char*> m_list;
};
Когда вы строите thing
копия stuff
сделано и хранится в классе. Когда объект разрушен, он автоматически освобождается m_list
,
thing
хранит слабую ссылку на stuff
,
Ваш класс будет хранить указатель (std::list<char*>* m_list
) или ссылка (std::list<char*>& m_list
). thing
сможет использовать ваш список любым способом, но он не должен отвечать за управление ресурсами. Если список находится в меньшей области, чем thing
тогда у вас останется свисающая ссылка.
thing getThing()
{
std::list<char*> list1;
thing object1(list1);
return object1; //bad - list will be deallocated, object1 will have a hanging reference
}
thing
хранит общий указатель на stuff
,
Этот метод больше всего похож retain
в Objective C. C ++ не имеет автоматического подсчета ссылок. Если вы хотите сохранить ссылку на объект с общим владением, вы можете использовать std::shared_ptr
, thing
магазины std::shared_ptr<std::list<char*>> m_list
,
std::shared_ptr<std::list<char*>> stuff = std::make_shared<std::list<char*>>();
thing object(stuff); //reference count incremented, even if stuff is destroyed object will still hold a valid reference