3

boost :: scoped_ptrではoperator*operator->宣言されたconst関数ですが、これらは戻りT&T*クライアントが基になるデータを変更できる可能性があります。これは論理的恒常性の概念に違反します(Myers、Effective C ++)

const関数にシグネチャが必要ではありませんか?

const T& operator*() const;
const T* operator->() const;
4

3 に答える 3

6

ここでの基本的な問題は、scoped_ptrオブジェクトがクラス オブジェクトではなくポインターのように動作することです (scoped_ptrインスタンスは実際にはクラス オブジェクトですが)。

Boost が提供するスマート ポインター クラスは、参照カウントや (この場合は) RAII セマンティクスなどの追加機能を提供しながら、生のポインター セマンティクスを可能な限り保持するように設計されています†</sup>。

そのために、 のoperator*()andoperator->()メンバーはscoped_ptr、その「constness 動作」が生のポインターの動作と本質的に一致するように記述されています。

「ダム」ポインターでこの状況を考えてみましょう。

// Can change either Foo or ptr.
Foo* ptr;
// Can't change Foo via ptr, although ptr can be changed.
const Foo* ptr;
// Can't change ptr, although Foo can be changed via ptr.
Foo* const ptr;
// Can't change Foo or ptr.
const Foo* const ptr;

アナログは次のscoped_ptrようになります。

// Can change either Foo or ptr.
scoped_ptr<Foo> ptr;
// Can't change Foo via ptr, although ptr can be changed.
scoped_ptr<const Foo> ptr;
// Can't change ptr, although Foo can be changed via ptr.
const scoped_ptr<Foo> ptr;
// Can't change Foo or ptr.
const scoped_ptr<const Foo> ptr;

scoped_ptr実際には未加工のポインタではありませんが、演算子の記述方法により、上記のコード スニペットが可能になります。

いずれの場合も、コードは を逆参照できる必要がありますptr。演算子を作成することにより、逆参照/メンバー アクセス演算子を sと非s のconst両方で呼び出すことができます。constconst scoped_ptr

scoped_ptr<Foo>ユーザーが a を宣言すると、次のメンバーが含まれることに注意してください。

Foo& operator*() const;
Foo* operator->() const;

ascoped_ptr<const Foo>には次のメンバーが含まれます。

const Foo& operator*() const;
const Foo* operator->() const;

したがって、ポインターの const-correctness 動作は、実際にはこの方法で保持されます。

†</sup>しかし、それ以上ではありません。

于 2011-07-17T00:58:45.603 に答える
1

boost::scoped_ptr では、operator* と operator-> は const 関数として宣言されていますが、T& と T* を返すため、クライアントが基になるデータを変更できる可能性があります。

「基になるデータ」は、スマート ポインター値の一部ではありません。2 つの (スマート) ポインターは、同じオブジェクト iff を指している場合は同等a == bです&*a == &*b

これは、論理定数の考え方に違反しています (Myers、Effective C++)

いいえ、違います:

スマート ポインターの論理値は、それが指している対象にのみ依存します。

スマート ポインターを逆参照しても、それが指すものは変わりません。

そのため、スマート ポインターを逆参照しても、その論理値 (または必要に応じてその状態) は変更されません。

QED

于 2011-11-24T04:39:27.960 に答える
0

Ascoped_ptr<T>は のようなものT*です。のようではありませんT* const

Ascoped_ptr<T const>は a のようなものでT const*(これは と書くことができますconst T*)、そうして初めて、ものを返すことが期待operator*されます。operator->const

于 2011-07-17T01:23:23.783 に答える