为什么unique_ptr operator->不是常量重载?

时间:2015-12-17 11:57:52

标签: c++ const smart-pointers

std::unique_ptr::operator->有签名

pointer operator->() const noexcept;

所以operator->是const但返回一个可变指针。这允许代码如下:

void myConstMemberFunction() const
{
    myUniquePtrMember->nonConstFunction();
}

为什么标准允许这样做,以及防止使用的最佳方法是什么?

2 个答案:

答案 0 :(得分:17)

将其视为普通指针:

int * const i;

是指向非const const的{​​{1}}指针。您可以更改int,但不能更改指针。

int

是指向int const * i; const的非const指针。您可以更改指针,但不能更改int

现在,对于int,问题是unique_ptr是在const内还是在<>之内。所以:

std::unique_ptr<int> const u;

就像第一个。您可以更改int,但不能更改指针。

你想要的是:

std::unique_ptr<int const> u;

您可以更改指针,但不能更改int。或者甚至可能:

std::unique_ptr<int const> const u;

在这里,您无法更改指针 int

请注意我总是将const放在右边?这有点不常见,但在处理指针时是必要的。 const始终适用于其左侧的内容,即*(指针为const)或int。请参阅http://kuhllib.com/2012/01/17/continental-const-placement/

撰写const int可能会让您认为int const *const - 指向非const int的指针,这是错误的。

答案 1 :(得分:7)

这复制了传统指针的语义。 const指针是一个无法变异的指针。但是,它指向的对象可以。

struct bar {
  void do_bar() {}
};

struct foo {
  void do_foo() const { b->do_bar(); } // OK
  bar* const b;
};

为了避免改变指针对象,你需要{const}指向const的unique_ptr等效指针,或者

const std::unique_ptr<const bar> b;