`const shared_ptr <T>`と `shared_ptr <const T>`の違いは何ですか?


115

次のようなC ++の共有ポインターのアクセサーメソッドを書いています。

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

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

したがってgetBar()、戻り値の型のconst-nessをサポートするためにboost::shared_ptrは、Barそれが指す変更を防ぐ必要があります。私の推測では、それshared_ptr<const Bar>は私が戻りたいタイプですconst shared_ptr<Bar>が、ポインタ自体が別のものを指すように再割り当てすることはできませんが、それが指すBarものの変更は許可さBarれます...しかし、私にはわかりません。確実に知っている人がこれを確認するか、間違った場合は修正していただければ幸いです。ありがとう!


3
それはまさにあなたが言ったことです。あなたは、事業者のためのドキュメントを見ることができる*し、->これを確認します。
サイアム2013

2
違いは何だT *constとはT const *?同じ。

3
@ H2CO3まったくありません。はconst通常、_preceedの内容を変更するためT *const、へのconstポインタTでありT const*、へのポインタconst Tです。また、そのconst前に何も付けずに使用しないことをお勧めします。
James

6
@JamesKanze、H2CO3のポイントです:違いT *constとはT const *違いと同じである const shared_ptr<T>shared_ptr<const T>
ジョナサンWakely

1
@JamesKanzeああ、でもそうです。T *const非constへのconstポインタなTので、そうですconst shared_ptr<T>。対照的に、T const *はへの非constポインターなconst Tので、ですshared_ptr<const T>

回答:


176

あなたが正しいです。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


1
また、通常のポインタ(const T *とT * constとT const *)について頭の後ろにあった質問にも答えました。:)私は、SO に関する質問が広すぎてほしくないので、これについては触れませんでした。これが、現在のタスクに関連する質問でした。とにかく、今はよくわかります。ありがとう!
Dave Lillethun 2013

9
お役に立てて嬉しいです。const T* p;', 'T const * p;とについて覚えている最後のヒントT * const p。がの同じ側に*あるものであるという意味で、セパレータをとして参照してください。const*
Cassio Neri

5
私の経験則では、const常に左側にあるものを指します。左側に何もない場合、それは右側にあるものです。
hochl 2017

hochi-const T * pはどうですか?T const * p ;?と同等
ヴラド

Cassio、戻り値の型const shared_ptr <T>の場合、constポインターには当てはまりませんが、非const関数では使用できないことを追加できます。
Vlad、

2

boost::shared_ptr<Bar const>Bar共有ポインタによるオブジェクトの変更を防ぎ ます。戻り値としてのconst in boost::shared_ptr<Bar> constは、返された一時変数に対して非const関数を呼び出せないことを意味します。実際のポインタ(例Bar* const:)の場合、完全に無視されます。

一般に、ここでも通常のルールが適用されます。constその前にあるものを変更boost::shared_ptr<Bar const>Barます。ではboost::shared_ptr<Bar> const、インスタンス化(boost::shared_ptr<Bar>constである式)です。


1
@gatopeichだからできるdelete
Marcin

@Marcinは詳しく説明できますか?
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;
}

std::make_shared()(C ++ 14以降)の使用をお勧めします。
Joel Bodenmann、2018

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

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.