Вопрос по c++, const, shared-ptr, boost – Разница между `const shared_ptr <T>` и `shared_ptr <const T>`?

87

m написание метода доступа для общего указателя в C ++, который выглядит примерно так:

class Foo {
public:
    return_type getBar() const {
        return m_bar;
    }

private:
    boost::shared_ptr m_bar;
}

Таким образом, чтобы поддержать постоянствоgetBar() тип возвращаемого значения должен бытьboost::shared_ptr что мешает модификацииBar это указывает на. мойУгадай в том, чтоshared_ptr это тип, который я хочу вернуть, чтобы сделать это, тогда какconst shared_ptr будет предотвращать переназначение самого указателя, чтобы указать на другойBar но разрешить модификациюBar что это указывает на ... Однако яЯ не уверен. Я'Буду признателен, если кто-то, кто знает наверняка, сможет подтвердить это или исправить меня, если я ошибаюсь. Спасибо!

@ H2CO3 Когда ничто не предшествуетconst, это изменяет то, что следует. Но это неt всегда очевидно:typedef int* PtrInt; const PtrInt pi;, Несмотря на внешность, он по определению эквивалентенint* constнеconst int*, (Это, IMO, аргумент убийцы. Ортогональность является хорошим аргументом --- так как вы должны поставитьconst после во многих случаях, почему не везде --- но этона самом деле не абсолют.) James Kanze
@JamesKanze, этос H2CO3 'Суть: разница междуT *const а такжеT const * такая же, как разница междуconst shared_ptr а такжеshared_ptr Jonathan Wakely
@JamesKanze О, но да.T *const константный указатель на неконстантныйTтак этоconst shared_ptr, По сравнению,T const * неконстантный указатель наconst Tтак и есть.shared_ptr user529758
@ H2CO3 Совсем нет.const обычно изменяет то, что _перед этим, такT *const этоconst указатель наT, а такжеT const* это указатель наconst T, И это'Лучше всего избегать использованияconst ничто не предшествует этому. James Kanze

Ваш Ответ

4   ответа
2

boost::shared_ptr предотвращает изменениеBar объект через общий указатель. В качестве возвращаемого значения const вboost::shared_ptr const означает, что вы не можете вызвать неконстантную функцию для возвращенного временного объекта; если бы это было для реального указателя (например,Bar* const), это было бы полностью проигнорировано.

В общем, даже здесь применяются обычные правила:const изменяет то, что ему предшествует: вboost::shared_ptr,Bar; вboost::shared_ptr const, Это'S экземпляр (выражениеboost::shared_ptr который является постоянным

@ Марчин, не могли бы вы разработать? gatopeich
@gatopeich Так что вы можетеdelete Это. Marcin
Почему бы 'Const» быть проигнорированнымреальный» указатель? gatopeich
1
#Check this simple code to understand... copy-paste the below code to check on any c++11 compiler

#include 
using namespace std;

class A {
    public:
        int a = 5;
};

shared_ptr<a> f1() {
    const shared_ptr</a><a> sA(new A);
    shared_ptr</a><a> sA2(new A);
    sA = sA2; // compile-error
    return sA;
}

shared_ptr</a><a> f2() {
    shared_ptr sA(new A);
    sA->a = 4; // compile-error
    return sA;
}

int main(int argc, char** argv) {
    f1();
    f2();
    return 0;
}
</a>
Могу ли я предложить использованиеstd::make_shared() (начиная с C ++ 14). Joel Bodenmann
127

Вы правы.shared_ptr p; похож наconst T * p; (или, что эквивалентно,T const * p;), то есть указанный объектconst в то время какconst shared_ptr p; похож наT* const p; Который означает, чтоp являетсяconst, В итоге:

shared_ptr<t> p;             ---> T * p;                                    : nothing is const
const shared_ptr<t> p;       ---> T * const p;                              : p is const
shared_ptr<const t=""> p;       ---> const T * p;       <=> T const * p;       : *p is const
const shared_ptr<const t=""> p; ---> const T * const p; <=> T const * const p; : p and *p are const.
</const></const></t></t>

То же самое относится и кweak_ptr а также .unique_ptr

Мое эмпирическое правило таково, чтоconst всегда относится к вещи на левой стороне этого. Если слева ничего нет,с правой стороны hochl
Вы также ответили на вопрос, который у меня был в затылке о регулярных указателях (const T * против T * const против T const *). :) Я не'не говоря об этом, потому что я нене хочу, чтобы мой вопрос о SO былтоже широкий, и это был вопрос, относящийся к моей текущей задаче. Во всяком случае, я думаю, что теперь я очень хорошо понимаю. Спасибо! Я Dave Lillethun
Я рад, что это помогло. Последний совет, который я использую, чтобы помнить оconst T* p;', 'T const * p; а такжеT * const p, Увидеть* в качестве разделителя в том смысле, чтоconst это то, что находится на той же стороне.* Cassio Neri
0

#include <memory>

int main(){
    std::shared_ptr<int> i = std::make_shared<int>(1);
    std::shared_ptr<int const=""> ci;

    // i = ci; // compile error
    ci = i;
    std::cout << *i << "\t" << *ci << std::endl; // both will be 1

    *i = 2;
    std::cout << *i << "\t" << *ci << std::endl; // both will be 2

    i = std::make_shared<int>(3);
    std::cout << *i << "\t" << *ci << std::endl; // only *i has changed

    // *ci = 20; // compile error
    ci = std::make_shared<int>(5);
    std::cout << *i << "\t" << *ci << std::endl; // only *ci has changed

}
</int></int></int></int></int></memory>

Похожие вопросы