Понимание C ++ std :: shared_ptr - PullRequest
0 голосов
/ 22 октября 2018

У меня есть вопрос, пожалуйста, пройдите следующую простую программу на C ++,

int main( )
{
 shared_ptr<int> sptr1( new int );
 shared_ptr<int> sptr2 = sptr1;
 shared_ptr<int> sptr3;
 shared_ptr<int> sptr4;
 sptr3 = sptr2;

 cout<<sptr1.use_count()<<endl;
 cout<<sptr2.use_count()<<endl;
 cout<<sptr3.use_count()<<endl;

 sptr4 = sptr2;

 cout<<sptr1.use_count()<<endl;
 cout<<sptr2.use_count()<<endl;
 cout<<sptr3.use_count()<<endl;

 return 0;
}

Вывод:

3
3
3
4
4
4

Как объекты sptr1 и sptr3 знают счетчик ссылокувеличивается при печати 4.

Насколько я знаю, счетчик ссылок является переменной в каждом shared_ptr объекте.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

A shared_ptr<T> обычно реализуется в виде двух указателей.Один для данных объекта, а другой для структуры, которая выглядит следующим образом:

[strong reference count]
[weak reference count]
[type-erased destroyer fptr]
[type-erased destroyer data]

, где [object ptr] указывает на фактический объект.

Когда вы копируете shared_ptr,он создает еще один указатель на вышеуказанные данные (и на реальный объект) и увеличивает его часть [strong reference count].Слабые указатели ведут себя аналогично, но вместо этого увеличивают [weak reference count] (когда сильное равно 0, а слабое ненулевое - вызывается уничтоженный по типу разрушитель, но блок управления остается).

В качестве отступления, когда выВызовите make_shared:

[strong reference count]
[weak reference count]
[type-erased destroyer fptr]
[object data]

, где указатель на объект теперь указывает на [object data] в конце блока управления.Это уменьшает количество выделений до одного.

Необходим отдельный указатель блока данных и управления из-за особенностей, таких как тот факт, что shared_ptr для производного может быть изменен на shared_ptr на базовый;это требует корректировки значения указателя во многих случаях.Точно так же конструктор псевдонимов общего ptr позволяет блоку управления и указанному объекту быть полностью не связанными.

Взято из ответа @ Estinox «что не является ответом», здесь это Channel9 говорит о том, как работает общий ptr.

0 голосов
/ 22 октября 2018

Насколько я знаю, счетчик ссылок является переменной в каждом объекте shared_ptr.

Нет, счетчик ссылок хранится в «блоке управления» в куче.Каждый экземпляр shared_ptr указывает на один и тот же «блок управления» и сохраняет его в живых (пока все экземпляры и все экземпляры weak_ptr, которые делятся с ними владельцами, не будут уничтожены).

...