Подтвердить что ты не робот

Const shared_ptr для shared_ptr

Как можно преобразовать shared_ptr, который указывает на объект const на shared_ptr, который указывает на неконстантный объект. Я пытаюсь сделать следующее:

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

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

Но это не сработает.

4b9b3361

Ответ 1

'boost:: const_pointer_cast' будет делать то, о чем вы просите, но обязательная вторая половина ответа заключается в том, что вы, вероятно, не должны его использовать. В 99% случаев, когда кажется, что вам нужно отбросить свойство const переменной, это означает, что у вас есть дефект дизайна. Const иногда бывает больше, чем просто украшение окон и отбрасывание его может привести к неожиданным ошибкам.

Не зная подробности своей ситуации, нельзя сказать наверняка. Но обсуждение const-cast не является полным без упоминания этого факта.

Ответ 3

Правильный способ должен быть таким

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

Ответ 4

std::const_cast_pointer выполняет второй управляемый указатель. После трансляции у вас есть записываемый указатель и оригинальный const-указатель. Путник остается тем же. Количество ссылок увеличилось на 1.

Обратите внимание, что const_cast является встроенным ключевым словом, но const_pointer_cast является функцией шаблона в пространстве имен std.

Затем записываемый указатель можно использовать для изменения значения из shared_ptr<const T>. IMHO записываемый указатель должен временно сохраняться в стеке; в противном случае должен быть дефект дизайна.

Однажды я написал небольшую тестовую программу, чтобы сделать это ясно для себя, которое я адаптировал для этого потока:

#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