Я не думаю, что правильно понял концепцию умных указателей.
Взгляните на этот MWE:
// Example program
#include <iostream>
#include <memory>
#include <string>
struct P{
float x, y;
P() : x(0.f), y(0.f){}
P(float x, float y) : x(x), y(y){}
P(P&& q) : x(q.x), y(q.y){}
P& operator=(P&& q){
x = q.x;
y = q.y;
return *this;
}
P& operator=(const P&) = delete;
P(const P&) = delete;
};
std::ostream& operator<<(std::ostream& out, const P& p){ out << p.x << " / " << p.y; return out;}
int main(){
P p1{1.f, 0.f};
P p2{2.f, 0.f};
std::unique_ptr<P> p1Ptr(std::make_unique<P>(std::move(p1)));
P* p2Ptr = &p2;
p1 = std::move(P{1.f, 1.f});
p2 = std::move(P{2.f, 2.f});
std::cout << " p1: " << p1 << "\n";
std::cout << "*p1: " << *p1Ptr << "\n";
std::cout << "*p1: " << *(p1Ptr.get()) << "\n";
std::cout << " p2: " << p2 << "\n";
std::cout << "*p2: " << *p2Ptr << std::endl;
}
Выход:
p1: 1 / 1
*p1: 1 / 0
*p1: 1 / 0
p2: 2 / 2
*p2: 2 / 2
Я ожидал, что std::unique_ptr также увидит изменение значения p1. Тем не менее, это не так. Как я могу этого добиться?
обратите внимание, что ходы избыточны, p1 = P{1.f, 1.f}; уже является назначением хода.
Это проблема XY — зачем вам std::unique_ptr, чтобы указать на существующий объект? Это побеждает его цель.
@Слава, если вы пытаетесь владеть структурой, в которой не определен ctor, то у вас нет другого выбора, кроме как указать на существующий объект? stackoverflow.com/questions/55141594/…





p1Ptr на самом деле не указывает на объект p1. Он указывает на безымянный объект, созданный std::make_unique с помощью конструктора P(P&&).
Нет смысла иметь точку std::unique_ptr<T> на объекте, определенном локально по отношению к функциональному блоку. Вся причина unique_ptr в том, что это единственный владелец объекта, на который он каким-то образом указывает. Поскольку вы используете средство удаления по умолчанию, это владение означает, что unique_ptr будет delete указателем на свой объект, пытаясь завершить свое время жизни. Но локальный объект функции уже имеет свое время жизни, «принадлежащее» функциональному блоку, и будет автоматически уничтожен, когда выполнение покинет этот блок; недействителен delete указатель на такой объект.
Итак, если мне нужны указатели на элементы в векторе, лучше использовать необработанные указатели?
Интеллектуальные указатели @infinitezero представляют владение, уникальное или совместно используемое, если вы просто указываете, но не используете необработанные указатели. Кстати, не рекомендуется иметь указатели на элементы в векторе из-за перераспределения.
Элементы в std::vector также уже «принадлежат», на этот раз vector.
Указатель
p1ptrуказывает на совершенно другой объект типаP. Он вообще не указывает и не ссылается наp1.*p1ptrиp1- два разных и отдельных объекта.