const shared_ptr para shared_ptr
-
19-09-2019 - |
Pergunta
Como se pode converter um shared_ptr que aponta para um objeto const para um shared_ptr que aponta para um objeto que não é consco. Estou tentando fazer o seguinte:
boost::shared_ptr<const A> Ckk(new A(4));
boost::shared_ptr<A> kk=const_cast< boost::shared_ptr<A> > Ckk;
Mas não funciona.
Solução
'Boost :: const_pointer_cast' fará o que você está solicitando, mas a segunda metade obrigatória da resposta é que você provavelmente não deve usá -lo. 99% do tempo em que parece que você precisa eliminar a propriedade const de uma variável, significa que você tem uma falha de design. Const às vezes é mais do que apenas o molho de janela e lançá -lo pode levar a bugs inesperados.
Sem saber mais detalhes da sua situação, não se pode dizer com certeza. Mas nenhuma discussão sobre const-cast está completa sem mencionar esse fato.
Outras dicas
usar boost::const_pointer_cast
, documentação.
A maneira correta deve ser isso
boost::shared_ptr<A> kk (boost::const_pointer_cast<A>(Ckk));
std::const_cast_pointer
faz um segundo ponteiro gerenciado. Após o elenco, você tem um ponteiro gravável e o ponteiro const original. O Pointee permanece o mesmo. A contagem de referência foi aumentada em 1.
Observe que const_cast
é uma palavra -chave incorporada, mas const_pointer_cast
é uma função de modelo no espaço para nome std
.
O ponteiro gravável pode então ser usado para alterar o valor de baixo do shared_ptr<const T>
. O ponteiro gravável só deve persistir temporariamente na pilha; Caso contrário, deve haver uma falha de design.
Certa vez, escrevi um pequeno programa de teste para deixar isso claro para mim mesmo, que adaptei para este tópico:
#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
}
Sob Unix ou Windows/Cygwin, compilar com
g++ -std=c++0x -lm const_pointer_cast.cpp