クラス内のget関数でのみ、プライベート変数にアクセスできないことを学びました。しかし、なぜコピーコンストラクタでアクセスできますか?
例:
Field::Field(const Field& f)
{
pFirst = new T[f.capacity()];
pLast = pFirst + (f.pLast - f.pFirst);
pEnd = pFirst + (f.pEnd - f.pFirst);
std::copy(f.pFirst, f.pLast, pFirst);
}
私の宣言:
private:
T *pFirst,*pLast,*pEnd;
私見、既存の答えは、これの「なぜ」を説明する悪い仕事をします-どんな振る舞いが有効であるかを繰り返すことに集中しすぎています。 「アクセス修飾子はクラスレベルで機能し、オブジェクトレベルでは機能しません。」 - そうだね。でも何で?
ここで最も重要な概念は、クラスを設計、作成、保守するプログラマーがOOカプセル化を望み、実装を調整する権限を与えられることを期待されていることです。 _class X
_を記述している場合、個々の_X x
_オブジェクトを、アクセス可能なコードで使用する方法だけでなく、次のようにエンコードします。
X
オブジェクトcooperateデザインの事後条件と不変条件を尊重しながら、意図した動作を提供します。それは単なるコピーコンストラクターでもありません-非常に多くの操作がクラスの2つ以上のインスタンスを含むことができます:比較、追加/乗算/除算、コピー構築、クローン作成、割り当てなどをしている場合、それは多くの場合です単純に他のオブジェクトのプライベートデータや保護データにアクセスする必要があるか、よりシンプルで高速な、または一般的に優れた機能の実装を許可する必要があります。
具体的には、これらの操作は特権アクセスを利用して次のようなことをしたい場合があります。
shared_ptr
_ s.auto_ptr<>
_は、構築中のオブジェクトの所有権を「移動」しますunordered_map
_メンバーですが、begin()
およびend()
イテレータのみを公開します-size()
への直接アクセスにより、reserve
容量を高速化できますコピー; at()
とinsert()
のみを公開し、それ以外の場合はthrow
....アクセス修飾子はクラスレベルで機能し、オブジェクトレベルでは機能しません。
つまり、同じクラスの2つのオブジェクトが互いにプライベートデータにアクセスできます。
主に効率のためです。 this == other
にアクセスするたびにother.x
かどうかをチェックすることは、無視できない実行時オーバーヘッドになります。
スコープの観点から考えると、意味論的にも論理的です。「プライベート変数を変更するとき、コードのどの部分を念頭に置く必要がありますか?」 –クラス全体のコードを念頭に置く必要があります。これは、実行時に存在するオブジェクトとは直交します。
また、コピーコンストラクターと代入演算子を記述するときに非常に便利です。
別のインスタンスのメンバーであっても、クラス内からクラスのプライベートメンバーにアクセスできます。
答えを理解するために、いくつかの概念を思い出したいと思います。
this
ポインターは、呼び出されるとすべての関数に渡されます。これは、this
ポインターが原因で、関数はその特定のインスタンスの変数を見つけることができます。プライベートかパブリックかは関係ありません。その関数内でアクセスできます。ここで、同じクラスの別のオブジェクトにポインターを渡すと。この2番目のポインターを使用して、プライベートメンバーにアクセスできます。
これがあなたの質問に答えることを願っています。
コピーコンストラクターはクラスのメンバー関数であるため、「プライベート」として宣言されたものであっても、クラスのデータメンバーにアクセスできます。