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