Я новичок в умных указателях. Тем не менее, у меня есть базовое понимание этого. Я заметил, что умные указатели должны быть уничтожены в обратном порядке их создания, иначе умные указатели могут вести себя неправильно. Рассмотрим следующую ситуацию:
sharedPtr<abc> my_ptr(new abc); //smart pointer created. Instance counter = 1.
func1(my_ptr); //copy constructor in smart pointer called. Instance counter=2
func2(my_ptr); //copy constructor in smart pointer called. Instance counter=3
func3(my_ptr); //copy constructor in smart pointer called. Instance counter=4
Теперь, разве не обязательно, что func3()
выходы сначала следуют func2()
, func1()
и наконец my_ptr.
Вопрос: Что, если my_ptr
выходит за рамки первого (& следовательно пытается удалить abc
), с func1()
, func2()
а также func3()
все еще ссылаясь на abc
(через умные указатели)?
На самом деле, то, что вы наблюдали, неправильно.
Смысл умного указателя состоит в том, чтобы снять ответственность за уничтожение объекта. Это означает, что объект будет удален, когда счетчик ссылок достигнет 0: не имеет значения, какой указатель уничтожается первым.
В вашем случае это будет когда my_ptr
выходит за рамки (при условии, что вы не делаете и сохраняете копию в своем func()
,
Вот какой счетчик ссылок должен быть:
{
sharedPtr<abc> my_ptr(new abc); //smart pointer created. Ref counter = 1.
func1(my_ptr); // Ref counter=2 while in func1
// Ref count is 1 again.
func2(my_ptr); // Ref counter=2 while in func2
// Ref count is 1 again.
func3(my_ptr); // Ref counter=2 while in func3
// Ref count is 1 again.
} // my_ptr goes out of scope, ref count reach 0, and abc is deleted.
Я не знаю о вашем обычае sharedPtr
, но для стандарта std::shared_ptr
это работает как (из ссылки):
Объект уничтожается, и его память освобождается, когда происходит одно из следующих действий:
последний оставшийся shared_ptr, владеющий объектом, уничтожается.
последнему оставшемуся файлу shared_ptr, которому принадлежит объект, присваивается другой указатель через operator = () или reset ().
Таким образом, для std::shared_ptr
Вы можете передать его или сделать столько копий, сколько захотите, порядок уничтожения этих копий не имеет значения.
Я заметил, что умные указатели необходимо уничтожать в обратном порядке их создания.
Ну, единственная причина существования общих умных указателей в том, что их не должно волновать, когда они уничтожаются. Когда последний разделяемый указатель уничтожается, он уничтожает объект, как в «последнем, кто покинет, выключает свет».