constshared_ptr вshared_ptr
-
19-09-2019 - |
Вопрос
Как можно преобразоватьshared_ptr, указывающий на константный объект, вshared_ptr, указывающий на неконстантный объект.Я пытаюсь сделать следующее:
boost::shared_ptr<const A> Ckk(new A(4));
boost::shared_ptr<A> kk=const_cast< boost::shared_ptr<A> > Ckk;
Но это не работает.
Решение
'boost::const_pointer_cast' сделает то, что вы просите, но обязательная вторая половина ответа заключается в том, что вам, вероятно, не следует его использовать.В 99% случаев, когда кажется, что вам нужно отказаться от свойства const переменной, это означает, что у вас есть недостаток дизайна.Const иногда представляет собой нечто большее, чем просто оформление показухи, и отказ от него может привести к неожиданным ошибкам.
Не зная подробностей вашей ситуации, нельзя сказать наверняка.Но ни одно обсуждение const-cast не будет полным без упоминания этого факта.
Другие советы
использовать boost::const_pointer_cast
, документация.
правильный путь должен быть таким
boost::shared_ptr<A> kk (boost::const_pointer_cast<A>(Ckk));
std::const_cast_pointer
создает второй управляемый указатель.После приведения у вас есть записываемый указатель и исходный константный указатель.Пунктир остается прежним.Количество ссылок увеличено на 1.
Обратите внимание, что const_cast
это встроенное ключевое слово, но const_pointer_cast
это функция шаблона в пространстве имен std
.
Затем записываемый указатель можно использовать для изменения значения из-под shared_ptr<const T>
.ИМХО, указатель на запись должен сохраняться в стеке только временно;в противном случае должен быть конструктивный недостаток.
Однажды я написал небольшую тестовую программу, чтобы прояснить это для себя, и адаптировал ее для этой темы:
#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
}
В UNIX или Windows/Cygwin скомпилируйте с помощью
g++ -std=c++0x -lm const_pointer_cast.cpp