"Const shared_ptr <T>" ve "shared_ptr <const T>" arasındaki fark nedir?


116

C ++ 'da paylaşılan bir işaretçi için aşağıdaki gibi bir erişimci yöntemi yazıyorum:

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

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

Dolayısıyla getBar(), dönüş türünün sabitliğini desteklemek için boost::shared_ptr, Barişaret ettiği değişikliklerin değiştirilmesini engelleyen bir olmalıdır . Benim tahminim ki shared_ptr<const Bar>ben oysa, bunu dönmek istiyorum türüdür const shared_ptr<Bar>farklı işaret edecek pointer kendisinin yeniden atanmasını engelleyecek Barancak değiştirilmesine izin Baro Ancak, emin değilim için ... işaret ettiğinden. Kesin olarak bilen biri bunu onaylarsa ya da yanlış anlarsam beni düzeltirse çok memnun olurum. Teşekkürler!


3
Aynen öyle söyledin. Operatörlerin belgelerine bakabilir *ve ->bunu onaylayabilirsiniz.
syam

2
Arasındaki fark nedir T *constve T const *? Aynısı.

3
@ H2CO3 Hiç de değil. constNe yani bunu _precedes, normalde değiştirir T *constbir olduğu constiçin işaretçi Tve T const*bir göstericidir const T. Önünde consthiçbir şey olmadan kullanmaktan kaçınmak en iyisidir .
James Kanze

6
H2CO3 en nokta @JamesKanze: arasındaki fark T *constve T const *arasındaki fark aynıdır const shared_ptr<T>veshared_ptr<const T>
Jonathan Wakely

1
@JamesKanze Oh ama evet. T *constconst olmayan bir göstericidir T, yani öyledir const shared_ptr<T>. Aksine, T const *const olmayan bir göstericidir const T, yani öyledir shared_ptr<const T>.

Yanıtlar:


176

Haklısın. shared_ptr<const T> p;benzer const T * p;(eşdeğer ya da T const * p;) olduğunu, sivri bir amacı constise const shared_ptr<T> p;benzer T* const p;olan aracı polup const. Özetle:

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.

Aynısı weak_ptrve için de geçerlidir unique_ptr.


1
Ayrıca, düzenli işaretçiler hakkında kafamın arkasındaki bir soruyu da cevapladınız (const T * vs. T * const vs. T const *). :) Bundan bahsetmedim çünkü SO konusundaki sorunuzun çok geniş olmasını istemiyordum ve bu benim mevcut görevimle ilgili soruydu. Her neyse, şimdi çok iyi anladığımı düşünüyorum. Teşekkürler!
Dave Lillethun

9
Yardımcı olmasına sevindim. Ben yaklaşık hatırlamak için kullandığı bir son ucu const T* p;', 'T const * p;ve T * const p. Neyin aynı tarafında *ne olduğu anlamında ayırıcı olarak görün . const*
Cassio Neri

5
Benim genel kuralım, consther zaman onun sol tarafındaki şeye atıfta bulunmasıdır. Solda hiçbir şey yoksa, sağ taraftaki şeydir.
hochl

hochi - peki ya const T * p; T const * p'ye eşdeğer ;?
Vlad

Cassio, döndürülen const shared_ptr <T> türünde, const olmayan işlevlerde kullanılamazken, const işaretçileri için doğru olmadığını ekleyebilirsiniz.
Vlad

2

boost::shared_ptr<Bar const>Barnesnenin paylaşılan işaretçi aracılığıyla değiştirilmesini önler . Bir dönüş değeri olarak, sabit boost::shared_ptr<Bar> const, döndürülen geçici üzerinde const olmayan bir işlevi çağıramayacağınız anlamına gelir; gerçek bir işaretçi Bar* constiçin olsaydı (örneğin ), tamamen göz ardı edilirdi.

Genel olarak, burada bile, olağan kurallar geçerlidir: constondan öncekini değiştirir: in boost::shared_ptr<Bar const>, the Bar; in boost::shared_ptr<Bar> const, bu somutlaştırmadır ( boost::shared_ptr<Bar>const.


1
@gatopeich Yani yapabilirsiniz delete.
Marcin

@Marcin detaylandırır mısın?
gatopeich

1
#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;
}

Kullanılmasını önerebilir miyim std::make_shared()(C ++ 14'ten beri).
Joel Bodenmann

0

@Cassio Neri'nin cevabına dayalı basit bir demostrasyon istiyorum:

#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

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.