Domanda

Come si può convertire uno shared_ptr che punta a un oggetto const ad uno shared_ptr che punta a un oggetto non const. Sto cercando di fare quanto segue:

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

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

Ma non funziona.

È stato utile?

Soluzione

'boost :: const_pointer_cast' farà quello che stai chiedendo, ma la seconda metà del obbligatoria la risposta è che probabilmente non dovrebbe usarlo. Il 99% del tempo in cui sembra che tu abbia bisogno di gettare via la proprietà const di una variabile, significa che si ha un difetto di progettazione. Const è a volte più di solo di facciata e la colata via può portare a bug inaspettati.

Senza conoscere i dettagli della vostra situazione non si può dire con certezza. Ma nessuna discussione di const-cast è completa senza menzionare questo fatto.

Altri suggerimenti

uso boost::const_pointer_cast, documentazione.

il modo corretto dovrebbe essere questo

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

std::const_cast_pointer fa un secondo puntatore gestito. Dopo il cast si dispone di un puntatore scrivibile e il const-puntatore originale. Il pointee rimane lo stesso. Il conteggio di riferimento è stato aumentato di 1.

Si noti che const_cast è una parola chiave incorporato, ma const_pointer_cast è una funzione template nel namespace std.

Il puntatore scrivibile può quindi essere utilizzato per modificare il valore da sotto il shared_ptr<const T>. IMHO il puntatore scrivibile dovrebbe persistere solo temporaneamente sullo stack; altrimenti ci deve essere un difetto di progettazione.

Una volta ho scritto un piccolo programma di test per rendere questo chiaro a me stesso che ho adattato per questa discussione:

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

Sotto Unix o Windows / Cygwin, compilare con

g++ -std=c++0x -lm const_pointer_cast.cpp
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top