shared_ptr const a shared_ptr
-
19-09-2019 - |
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.
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