Подсчет ссылок на C ++ shared_ptr при привязке другого умного указателя к указателю, возвращенному get - PullRequest
0 голосов
/ 19 июня 2019

Согласно странице "C ++ Primer", стр. 466, привязка другого умного указателя к указателю, возвращенному get(), является ошибкой.Далее следует некоторый код и дальнейшие пояснения.У меня возникают проблемы с пониманием части объяснения, в котором говорится дословно:

В этом случае и p, и q указывают на одну и ту же память.Поскольку они были созданы независимо друг от друга, каждый имеет счетчик ссылок 1. Когда блок, в котором было определено q, заканчивается, q уничтожается.Уничтожение q освобождает память, на которую указывает q.Это превращает p в висячий указатель, что означает, что то, что происходит, когда мы пытаемся использовать p, не определено.

Этот вопрос связан с предыдущим вопросом, который я задал, Понимание C ++ std :: shared_ptr при использовании с временными объектами , где я играл с моими собственными примерами и ошибочно полагал, чтовременный shared_ptr был создан в строке 5.

shared_ptr<int> p(new int(42));
int *q = p.get();
{ // new block
  // undefined: two independent shared_ptrs point to same memory
  shared_ptr<int>(q); 
  cout << p.use_count() << '\n' << q.use_count() <<'\n';
}
Output:
1
0

В соответствии с объяснением выше, оба p и q имеют счетчик ссылок 1.

Но при добавлении оператора печати для вывода счетчик ссылок.Я понял, что p имеет счетчик использования 1, а q имеет счетчик использования 0. Разве q также не должен иметь счетчик использования 1?Или я что-то упустил?Я бы понял, если q счетчик ссылок был 0 после блока.

Ответы [ 2 ]

3 голосов
/ 19 июня 2019

shared_ptr<int>(q);

Это создает shared_ptr с именем q и эквивалентно

shared_ptr<int> q;

, который не указывает ни на что и поэтому его счет0

Если вы хотите, чтобы второй shared_ptr указывал на q, вам нужен

 shared_ptr<int> p2(q); 
2 голосов
/ 19 июня 2019

В книге есть ошибка - во внутреннем блоке q является пустым shared_ptr, не связанным с p.get().

Кажется, что это не вошло ни в какие опубликованные опечатки.

Следующее должно выводить то, что вы ожидаете, и быть таким неопределенным, как задумал автор:

shared_ptr<int> p(new int(42));
{ 
  shared_ptr<int> q(p.get()); 
  cout << p.use_count() << '\n' << q.use_count() <<'\n';
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...