std: :shared_ptr оператор= изменяет объект, а не значение указателя?

#c

#c

Вопрос:

В приведенной ниже небольшой программе я хотел иметь возможность изменять значение внутри M m , изменяя значение s . Но, видимо, я не могу этого сделать. Один из способов, который мог бы сработать, — это изменить необработанный указатель, но это небезопасно:

 #include <iostream>
#include <memory>
class M{
  public:
  std::shared_ptr<int> t;
};
std::shared_ptr<int> s;
int main() {
  M m;
  m.t = s;
  s = std::make_shared<int>(5);
  std::cout << m.t << std::endl; //prints 0
}
  

В этой маленькой программе я думал, что при выполнении s = std::make_shared<int>(5) , s внутренний указатель будет указывать на 5 . Однако вместо этого он заменяет значение s другим значением, поэтому m.t не указывает на новое s .

Разве невозможно сделать то, что я хочу?

Комментарии:

1. Вся функция общего указателя заключается в безопасном обходе указателя, как если бы это был просто необработанный указатель. Это означает, что m.t = s просто копирует указатель, который s в данный момент управляет, и сохраняет его в t . Затем он обновляет свой внутренний счетчик ссылок, так что, если один из s или t выйдет за пределы области видимости, указатель не будет удален. Если вы затем измените то, на что s указывает, это не должно измениться t , потому что t не знает об s .

2. Если вы также хотите изменить содержимое s эффектов m.t , тогда вам нужно изменить содержимое s . Попробуйте *s = 5; std::cout << *m.t << std::endl; . Что касается этого, интеллектуальные указатели в точности напоминают, как в этом случае будут работать необработанные указатели. Демонстрация на coliru

3. Вы поменяли порядок местами. s = std::make_shared<int>(5); Сначала сделайте, затем сделайте m.t = s; . После этого вы можете *s = 6; или *m.t = 7; , любой из которых повлияет на другой общий интеллектуальный указатель.