¿Diferencia entre ` const shared ptr `y `shared ptr'?


Estoy escribiendo un método de acceso para un puntero compartido en C++ que va algo como esto:

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

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

Así que para soportar la constancia de getBar() el tipo devuelto debe ser un boost::shared_ptr que impida la modificación del Bar al que apunta. Mi conjetura es que shared_ptr<const Bar> es el tipo que quiero volver a hacer eso, mientras que const shared_ptr<Bar> evitaría la reasignación del puntero para apuntar a un Bar diferente, pero permitiría la modificación del Bar al que apunta... Sin embargo, no estoy seguro. Yo apreciaría si alguien que lo sabe con seguridad pudiera confirmar esto o corregirme si me equivoco. ¡Gracias!

Author: Dave Lillethun, 2013-07-22

4 answers

Tienes razón. shared_ptr<const T> p; es similar a const T * p; (o, equivalentemente, T const * p;), es decir, el objeto puntiagudo es const mientras que const shared_ptr<T> p; es similar a T* const p; lo que significa que p es const. En resumen:

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.

Lo mismo vale para weak_ptr y unique_ptr.

 118
Author: Cassio Neri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-22 17:15:17

boost::shared_ptr<Bar const> evita la modificación de la Bar objeto a través del puntero compartido. Como valor devuelto, el const in boost::shared_ptr<Bar> const significa que no puedes llame a una función no-const en el temporal devuelto; si fuera para un puntero real (por ejemplo, Bar* const), sería completamente ignorar.

En general, incluso aquí, se aplican las reglas habituales: const modifica lo que lo precede: en boost::shared_ptr<Bar const>, el Bar; en boost::shared_ptr<Bar> const, es la instanciación (la expresión boost::shared_ptr<Bar> que es const.

 2
Author: James Kanze,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-22 17:24:00
#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;
}
 1
Author: vivek2k6,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-17 12:37:03

Me gustaría una demostración simple basada en la respuesta 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

}
 0
Author: Jónás Balázs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-07 13:52:14