【问题标题】:Difference between `const shared_ptr<T>` and `shared_ptr<const T>`?`const shared_ptr<T>` 和 `shared_ptr<const T>` 之间的区别?
【发布时间】:2013-07-21 12:40:06
【问题描述】:

我正在为 C++ 中的共享指针编写一个访问器方法,如下所示:

class Foo {
public:
    return_type getBar() const {
        return m_bar;
    }

private:
    boost::shared_ptr<Bar> m_bar;
}

所以为了支持getBar() 的常量性,返回类型应该是boost::shared_ptr,它可以防止修改它指向的Bar。我的 猜测shared_ptr&lt;const Bar&gt; 是我想要返回的类型,而 const shared_ptr&lt;Bar&gt; 会阻止重新分配指针本身以指向不同的 Bar 但允许修改 @它指向的 987654328@... 但是,我不确定。如果确定知道的人可以确认这一点,或者如果我弄错了,我将不胜感激。谢谢!

【问题讨论】:

  • 正是你所说的。您可以查看操作员 *-&gt; 的文档来确认这一点。
  • T *constT const * 有什么区别?一样。
  • @H2CO3 一点也不。 const 通常会修改 _precedes 的内容,因此 T *const 是指向 Tconst 指针,T const* 是指向 const T 的指针。最好避免使用前面没有任何内容的const
  • @JamesKanze,这就是H2CO3的意思:T *constT const *之间的区别与const shared_ptr&lt;T&gt;shared_ptr&lt;const T&gt;之间的区别相同
  • @H2CO3 我误解了您所说的“相同”的含义。但是我很好奇一件事:你写T *const,那你为什么不写shared_ptr&lt;T&gt; const呢?同样,你写了T const*,那为什么不写shared_ptr&lt;T const&gt;呢?为什么不正交,并把const 放在任何地方(因为在某些情况下你必须把它放在后面)。

标签: c++ boost constants shared-ptr


【解决方案1】:

你是对的。 shared_ptr&lt;const T&gt; p; 类似于const T * p;(或等价于T const * p;),即指向的对象是const,而const shared_ptr&lt;T&gt; p; 类似于T* const p;,这意味着pconst。总结:

shared_ptr<T> p;             ---> T * p;                                    : nothing is const
const shared_ptr<T> p;       ---> T * const p;                              : p is const
shared_ptr<const T> p;       ---> const T * p;       <=> T const * p;       : *p is const
const shared_ptr<const T> p; ---> const T * const p; <=> T const * const p; : p and *p are const.

weak_ptrunique_ptr 也是如此。

【讨论】:

  • 您还回答了我脑后关于常规指针的问题(const T* vs. T* const vs. T const *)。 :) 我没有提到这一点,因为我不希望我对 SO 的问题 宽泛,而这是与我当前任务相关的问题。无论如何,我想我现在已经很明白了。谢谢!
  • 我很高兴它有帮助。我用来记住const T* p;', 'T const * p;T * const p 的最后一个提示。将* 视为分隔符,因为const* 的同一侧。
  • 我的经验法则是const 总是指它左边的东西。如果左边什么都没有,那就是右边的东西。
  • hochi - const T * p;相当于 T const * p;?
  • Cassio,您可以添加,在返回类型为 const shared_ptr 的情况下,它不能用于非常量函数,而对于 const 指针则不是这样。
【解决方案2】:

boost::shared_ptr&lt;Bar const&gt; 防止修改 Bar 对象通过共享指针。作为返回值, boost::shared_ptr&lt;Bar&gt; const 中的 const 表示您不能 在返回的临时对象上调用非常量函数;如果是的话 对于一个真正的指针(例如Bar* const),它完全是 忽略。

一般来说,即使在这里,通常的规则也适用:const 修改 前面是什么:在boost::shared_ptr&lt;Bar const&gt;Bar; 在boost::shared_ptr&lt;Bar&gt; const 中,它是实例化( 表达式boost::shared_ptr&lt;Bar&gt; 是常量。

【讨论】:

  • @gatopeich 所以你可以delete它。
  • @Marcin 你能详细说明一下吗?
【解决方案3】:
#Check this simple code to understand... copy-paste the below code to check on any c++11 compiler

#include <memory>
using namespace std;

class A {
    public:
        int a = 5;
};

shared_ptr<A> f1() {
    const shared_ptr<A> sA(new A);
    shared_ptr<A> sA2(new A);
    sA = sA2; // compile-error
    return sA;
}

shared_ptr<A> f2() {
    shared_ptr<const A> sA(new A);
    sA->a = 4; // compile-error
    return sA;
}

int main(int argc, char** argv) {
    f1();
    f2();
    return 0;
}

【讨论】:

  • 我建议使用std::make_shared()(C++14 起)。
【解决方案4】:

我想根据@Cassio Neri 的回答做一个简单的演示:

#include <memory>

int main(){
    std::shared_ptr<int> i = std::make_shared<int>(1);
    std::shared_ptr<int const> ci;

    // i = ci; // compile error
    ci = i;
    std::cout << *i << "\t" << *ci << std::endl; // both will be 1

    *i = 2;
    std::cout << *i << "\t" << *ci << std::endl; // both will be 2

    i = std::make_shared<int>(3);
    std::cout << *i << "\t" << *ci << std::endl; // only *i has changed

    // *ci = 20; // compile error
    ci = std::make_shared<int>(5);
    std::cout << *i << "\t" << *ci << std::endl; // only *ci has changed

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    相关资源
    最近更新 更多