指向unique_ptr的指针 - 这是一个漏洞吗?

Pla*_*ove 1 c++ unique-ptr

这似乎是一种避免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;
}
Run Code Online (Sandbox Code Playgroud)

Bat*_*eba 10

从某种意义上说,C++充满了绅士们的协议.换句话说,这种语言让你有能力用脚射击自己.

没有什么可以阻止你取一个地址std::unique_ptr.如果你真的觉得这很令人反感,那么你可以继承std::unique_ptr并使用包含静态断言的函数重载address-of运算符.

但即使你这样做,你也可以绕过它std::addressof!

  • @StoryTeller:绝对。这就是为什么如今的编程是绅士的职业:还是击败神职人员。 (2认同)
  • 平均工资也更高。 (2认同)
  • 英语不是我的主要语言,我不知道[绅士协议]的表达方式(https://en.wikipedia.org/wiki/Gentlemen%27s_agreement).它实际上很好地定义了计算机科学. (2认同)

gez*_*eza 5

您实际上将您的真实问题发表了评论:

我的理解unique_ptr是应该使用它来确保您在任何时候都只有一个指向一个对象的指针。

不,这是错误的。您可以轻松地执行以下简单操作:

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

unique_ptr 尝试设计以确保您只能拥有一个unique_ptr对象。但是,即使不使用裸指针,它也可以确保这一点。使用裸露的指针,可以轻松避开此设计:

std::unique_ptr<int> a(new int);
std::unique_ptr<int> b(a.get());
Run Code Online (Sandbox Code Playgroud)

此处,b指向与相同的对象a,因此该程序具有未定义的行为(因为该int对象将被删除两次)。

unique_ptr目的是显示所有权。因为只能有一个unique_ptr指向对象的对象(忽略了我之前提到的“ hack”),所以它unique_ptr拥有指向的对象,并且当unique_ptr调用的析构函数时,它将删除指向的对象。

  • @PlastyGrove 实际上`int* b = new int; std::unique_ptr&lt;int&gt; a(b);` 有效,不需要 `.get`。 (2认同)