156 votes

Différence entre `const shared_ptr<T>` et `shared_ptr<const T>` ?

J'écris une méthode d'accès pour un pointeur partagé en C++ qui ressemble à ceci :

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

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

Donc pour soutenir la constance de getBar() le type de retour doit être un boost::shared_ptr qui empêche la modification de la Bar qu'il indique. Mon devinez c'est que shared_ptr<const Bar> est le type que je veux retourner pour faire cela, alors que const shared_ptr<Bar> empêcherait la réaffectation du pointeur lui-même pour pointer vers un autre objet Bar mais permettent de modifier les Bar qu'il pointe vers... Cependant, je ne suis pas sûr. J'apprécierais que quelqu'un qui en est sûr puisse soit le confirmer, soit me corriger si je me trompe. Merci !

249voto

Cassio Neri Points 6095

Vous avez raison. shared_ptr<const T> p; est similaire à const T * p; (ou, de manière équivalente, T const * p; ), c'est-à-dire que l'objet pointé est const alors que const shared_ptr<T> p; est similaire à T* const p; ce qui signifie que p es const . En résumé :

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.

Il en va de même pour weak_ptr y unique_ptr .

3voto

Jónás Balázs Points 583

Je voudrais faire une démonstration simple basée sur la réponse de @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

}

2voto

James Kanze Points 96599

boost::shared_ptr<Bar const> empêche la modification de la Bar par le biais du pointeur partagé. En tant que valeur de retour, le const en boost::shared_ptr<Bar> const signifie que vous ne pouvez pas appeler une fonction non-const sur le temporaire retourné ; si c'était pour un pointeur réel (par ex. Bar* const ), il serait complètement ignorée.

En général, même ici, les règles habituelles s'appliquent : const modifie ce qui le précède : dans boost::shared_ptr<Bar const> le Bar ; sur boost::shared_ptr<Bar> const c'est l'instanciation (l' expression boost::shared_ptr<Bar> qui est constant.

1voto

vivek2k6 Points 109
#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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X