Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const shared_ptr to shared_ptr

How can one convert a shared_ptr that points to a const object to a shared_ptr that points to a non-const object. I am trying to do the following :

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

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

But it does not work.

like image 691
user152508 Avatar asked Dec 16 '09 08:12

user152508


4 Answers

'boost::const_pointer_cast' will do what you're asking for, but the obligatory second half of the answer is that you probably shouldn't use it. 99% of the time when it seems like you need to cast away the const property of a variable, it means that you have a design flaw. Const is sometimes more than just window dressing and casting it away may lead to unexpected bugs.

Without knowing more details of your situation one can't say for certain. But no discussion of const-cast is complete without mentioning this fact.

like image 191
Alan Avatar answered Oct 16 '22 14:10

Alan


use boost::const_pointer_cast, documentation.

like image 45
Nikola Smiljanić Avatar answered Oct 16 '22 13:10

Nikola Smiljanić


the proper way should be this

boost::shared_ptr<A> kk (boost::const_pointer_cast<A>(Ckk));
like image 2
YeenFei Avatar answered Oct 16 '22 14:10

YeenFei


std::const_cast_pointer makes a second managed pointer. After the cast you have a writable pointer and the original const-pointer. The pointee remains the same. The reference count has been increased by 1.

Note that const_cast is a builtin keyword, but const_pointer_cast is a template function in namespace std.

The writable pointer can then be used to change the value from under the shared_ptr<const T>. IMHO the writable pointer should only persist temporarily on the stack; otherwise there must be a design flaw.

I once wrote a small test program to make this clear to myself which I adapted for this thread:

#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
}

Under UNIX or Windows/Cygwin, compile with

g++ -std=c++0x -lm const_pointer_cast.cpp
like image 2
Andreas Spindler Avatar answered Oct 16 '22 13:10

Andreas Spindler