【问题标题】:const shared_ptr to shared_ptr常量 shared_ptr 到 shared_ptr
【发布时间】:2010-12-27 03:52:02
【问题描述】:

如何将指向 const 对象的 shared_ptr 转换为指向非 const 对象的 shared_ptr。 我正在尝试执行以下操作:

boost::shared_ptr<const A> Ckk(new A(4));

boost::shared_ptr<A> kk=const_cast< boost::shared_ptr<A> > Ckk;

但它不起作用。

【问题讨论】:

    标签: boost shared-ptr


    【解决方案1】:

    'boost::const_pointer_cast' 会做你要求的,但答案的后半部分是你可能不应该使用它。 99% 的情况下,当您似乎需要抛弃变量的 const 属性时,这意味着您存在设计缺陷。 const 有时不仅仅是装点门面,扔掉它可能会导致意想不到的错误。

    在不了解您的情况的更多细节的情况下,无法确定。但是,如果不提及这个事实,对 const-cast 的讨论是不完整的。

    【讨论】:

    • 使用const_pointer_cast 并不是比您估计的更频繁的设计缺陷。例如,标准容器只能使用可转换为所包含元素类型的类型进行操作。因此,即使在逻辑上是正确的,以下也是不可能的:vector&lt;shared_ptr&lt;T&gt;&gt; cont; shared_ptr&lt;const T&gt; a; cont.push_back(a);
    • @jons34yp:这在逻辑上没有任何正确性。你得到了一个 const 指针;这意味着您不允许以非常量方式使用它。如果你有一个非常量指针列表,并且你想在其中放入一个 const 指针,那就很难了。通过 const-casting 它,您违反了与给您该指针的人的合同(该合同是您不能更改它)。这对于常规指针和 shared_ptr 的一样都是正确的。
    • const_pointer_cast 在扩展共享指针的行为时会很有用。但是,如果您是真正可能为提升做出贡献的人,您可能只应该这样做。
    • @Brent "扩展共享指针的行为" 你是什么意思?
    【解决方案2】:

    使用boost::const_pointer_castdocumentation.

    【讨论】:

      【解决方案3】:

      正确的方法应该是这样

      boost::shared_ptr<A> kk (boost::const_pointer_cast<A>(Ckk));
      

      【讨论】:

        【解决方案4】:

        std::const_cast_pointer 创建第二个托管指针。在演员表之后,你有一个可写的指针原来的常量指针。指针保持不变。引用计数增加了 1。

        注意const_cast 是一个内置关键字,但const_pointer_cast 是命名空间std 中的一个模板函数。

        然后可以使用可写指针更改shared_ptr&lt;const T&gt; 下的值。恕我直言,可写指针应该只暂时保留在堆栈上;否则一定有设计缺陷。

        我曾经写了一个小测试程序来让自己明白这一点,我为这个线程做了调整:

        #include <memory>
        #include <iostream>
        #include <cassert>
        
        using namespace std;
        
        typedef shared_ptr<int> int_ptr;
        typedef shared_ptr<const int> const_int_ptr;
        
        int main(void)
        {
            const_int_ptr Ckk(new int(1));
        
            assert(Ckk.use_count() == 1);
            cout << "Ckk = " << *Ckk << endl;
        
            int_ptr kk = const_pointer_cast<int>(Ckk); // obtain a 2nd reference
            *kk = 2;                   // change value under the const pointer
        
            assert(Ckk.use_count() == 2);
            cout << "Ckk = " << *Ckk << endl;      // prints 3
        }
        

        在 UNIX 或 Windows/Cygwin 下,使用编译

        g++ -std=c++0x -lm const_pointer_cast.cpp
        

        【讨论】:

        • "prints 3" - 3 是从哪里来的?是错字吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-08
        • 2018-07-16
        • 1970-01-01
        • 1970-01-01
        • 2011-09-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多