Указатель на unique_ptr - это лазейка? - PullRequest
0 голосов
/ 25 сентября 2018

Кажется, что простой способ обойти unique_ptr - это использовать указатель на объект unique_ptr.И это не сложно.Таким образом, использование unique_ptr является своего рода джентльменским соглашением и не является действительно обязательным?

#include <iostream>
#include <memory>
using namespace std;

class Box {
  public:
    int num;
};

void update_box(unique_ptr<Box>* pu);

int main(){
  unique_ptr<Box> b{new Box};
  unique_ptr<Box>* u = &b;
  update_box(u);
  cout << b->num << endl; // Outputs 99.
  return 0;
}

void update_box(unique_ptr<Box>* pu) {
  (*pu)->num = 99;
}

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Вы на самом деле поставили свой реальный вопрос в комментарии:

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

Нет, это неправильно.Вы можете легко сделать простое:

std::unique_ptr<int> a(new int);
int *b = a.get(); // b points to the same object as a

Дизайн unique_ptr пытается , чтобы гарантировать, что вы можете иметь только один unique_ptr для объекта.Но даже это может обеспечить это, только если вы не используете голые указатели.С голыми указателями легко обойти этот дизайн:

std::unique_ptr<int> a(new int);
std::unique_ptr<int> b(a.get());

Здесь b указывает на тот же объект, что и a, поэтому эта программа имеет неопределенное поведение (потому что объект int будетбыть удаленным дважды).

unique_ptr намеревается показать владение .Так как может быть только один unique_ptr, который может указывать на объект (игнорируя «взлом», который я представил ранее), unique_ptr владеет указанным объектом, и, поскольку вызывается деструктор unique_ptr, он удалитостроконечный предмет.

0 голосов
/ 25 сентября 2018

C ++ в некотором смысле полон джентльменских соглашений.Другими словами, язык дает вам возможность выстрелить себе в ногу.

Ничто не мешает вам взять адрес std::unique_ptr.Если вы действительно посчитаете это неприятным, то вы можете унаследовать от std::unique_ptr и перегрузить оператор адресации функцией, содержащей статическое утверждение.

Но даже если вы это сделаете, вы можетеобойти это с std::addressof!

...