Question

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.

Was it helpful?

Solution

'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.

OTHER TIPS

use boost::const_pointer_cast, documentation.

the proper way should be this

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

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top