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 supporter la const-ness de getBar()
, le type de retour doit être un boost::shared_ptr
Qui empêche la modification du Bar
auquel il pointe. Mon suppose est que shared_ptr<const Bar>
Est le type que je veux revenir pour le faire, alors que const shared_ptr<Bar>
Empêcherait la réaffectation du pointeur lui-même pour pointer vers un autre Bar
mais permet la modification du Bar
vers lequel il pointe ... Cependant, je ne suis pas sûr. J'apprécierais que quelqu'un qui en soit sûr puisse soit confirmer cela, soit me corriger si je me suis trompé. Merci!
Vous avez raison. shared_ptr<const T> p;
est similaire à const T * p;
(ou équivalent, 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
est 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
et unique_ptr
.
boost::shared_ptr<Bar const>
empêche la modification de l'objet Bar
par le pointeur partagé. En tant que valeur de retour, le const dans boost::shared_ptr<Bar> const
signifie que vous ne pouvez pas appeler une fonction non-const sur le temporaire renvoyé; s’il s’agissait d’un pointeur réel (par exemple, Bar* const
), il serait complètement ignoré.
En général, même ici, les règles habituelles s’appliquent: const
modifie ce qui le précède: in boost::shared_ptr<Bar const>
, le Bar
; dans boost::shared_ptr<Bar> const
, c'est l'instanciation (l'expression boost::shared_ptr<Bar>
qui est 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;
}
J'aimerais 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
}