Разница между `константный общая ПТР " и " общая ПТР `?


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

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

private:
    boost::shared_ptr<Bar> m_bar;
}

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

4 82

4 ответа:

вы правы. shared_ptr<const T> p; похож на const T * p; (или, что то же самое,T const * p;), то есть, указанный объект const, тогда как const shared_ptr<T> 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.

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

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

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

#Check this simple code to understand... copy-paste the below code to check on any c++11 compiler

#include <memory>
using namespace std;

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

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

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

int main(int argc, char** argv) {
    f1();
    f2();
    return 0;
}

Я хотел бы простой демострации на основе ответа @Cassio Neri:

#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

}