2

shared_ptr コピー コンストラクターについて混乱があります。次の 2 行を検討してください。

  1. これは、shared_ptr オブジェクトへの「定数」参照であり、別の shared_ptr オブジェクトが初期化されるようにコピー コンストラクターに渡されます。

  2. コピー コンストラクターは、メンバー データ (「参照カウンター」) もインクリメントすることになっています。これは、すべての shared_ptr オブジェクト間で共有されます。これは、各 shared_ptr オブジェクトにまだいくつあるかを伝える整数への参照/ポインターであるためです。生きている。

しかし、コピー コンストラクターが参照カウント メンバー データをインクリメントしようとすると、参照渡しされた shared_ptr の const-ness に「ヒット」しませんか? または、コピー コンストラクターは const_cast 演算子を内部的に使用して、引数の const-ness を一時的に削除しますか?

4

5 に答える 5

5

発生している現象は、共有ポインターに特有のものではありません。典型的な原始的な例を次に示します。

struct Foo
{
    int * p;
    Foo() : p(new int(1)) { }
};

void f(Foo const & x)  // <-- const...?!?
{
    *x.p = 12;         // ...but this is fine!
}

の中にx.ptypeがあるのは事実ですが、!ではありません。つまり、 を変更することはできませんが、変更することはできます。int * constfint const * constx.p*x.p

これは基本的に、共有ポインター コピー コンストラクター (*p参照カウンターの役割を果たす場所) で行われていることです。

于 2012-09-09T20:11:25.900 に答える
3

他の答えは正しいですが、それらがどのように適用されるかはすぐにはわからないかもしれません. 私たちが持っているのは次のようなものです:

template <class T>
struct shared_ptr_internal {
    T *data;
    size_t refs;
};

template <class T>
class shared_ptr {
    shared_ptr_internal<T> *ptr;
public:
    shared_ptr(shared_ptr const &p) { 
        ptr = p->ptr;
        ++(ptr->refs);
    }
    // ...
};

ここで重要な点は、shared_ptr には、参照カウントを含む構造体へのポインターだけが含まれているということです。shared_ptrそれ自体がであるという事実は、それがconst指しているオブジェクト (私が と呼んだものshared_ptr_internal) には影響しません。shared_ptrそのため、それ自体がである場合でもconst、参照カウントを操作することは問題ではありません (また、const_castまたはmutableどちらも必要ありません)。

おそらく実際には、これとは少し異なるコードを構造化することになるでしょう。特に、通常は、参照カウントを操作するコードをさらに (すべて?) 追加して、shared_ptr_internal (または、親shared_ptrクラスのものをいじるのではなく、それ自体を呼び出すことにします。

また、通常はweak_ptrs もサポートします。これを行うには、同じオブジェクトweak_ptrを指す の数に対する 2 番目の参照カウントがあります。shared_ptr_internal参照カウントが 0 になったときに最後の pointee オブジェクトを破棄しますが、参照カウントの両方が 0 になったときにshared_ptrのみオブジェクトを破棄します。shared_ptr_internalshared_ptr weak_ptr

于 2012-09-10T00:51:47.013 に答える
2

次のように、引数の競合を継承しない内部ポインターを使用します。

(*const_ref.member)++;

有効です。

于 2012-09-09T19:40:40.213 に答える
0

うわー、これはなんと目を見張るものでした!混乱の原因を突き止めることができた皆さんのおかげで、私は常に次の(「a」には「b」のアドレスが含まれている)がすべて同等であると想定していました。

int const  *a = &b;    // option1
const int  *a = &b;    // option2
int * const a = &b;    // option3

しかし、私は間違っていました!最初の2つのオプションのみが同等です。3番目は完全に異なります。

option1またはoption2を使用すると、「a」は必要なものを指すことができますが、指す内容を変更することはできません。

オプション3では、「a」が何を指すかを一度決定すると、他のものを指すことはできません。ただし、ポイントしている内容は自由に変更できます。したがって、shared_ptrがoption3を使用することは理にかなっています。

于 2012-09-10T11:30:56.273 に答える
0

ポインタは一定ですが、指している値ではありません。

于 2012-09-09T20:13:26.120 に答える