OOPで公開されている方法の1つの役割は、オブジェクトが常に有効な状態になっていることを確認することです(これは、ポッドの種類がmemcpy
ではないという重要な理由の1つです)。例えば。非常に基本的な、知識をひけらかす例:(/ javaのようなセットを無視して取得してください):この例ではオブジェクトのスライシングがカプセル化を中断しますか?
class Restricted {
protected:
int a;
public:
Restricted() : a{0} {}
// always returns a non-negative number
auto get() const -> int {
return a;
}
auto set(int pa) -> void {
if (pa < 0)
a = 0;
else
a = pa;
}
auto do_something() {
// here I code with the assumption that
// a is not negative
}
};
は、クラスRestricted
はRestricted
オブジェクトは常に非負の数を保持しているようにモデル化されています。これは私がRestricted
の有効な状態を定義する方法です。インタフェースを見ると、Restricted ::get
は常に負でない数値を返すと言えます。ユーザーがRestricted
に負の数を保持させる方法はありません。
a
は、オプションで簡単にクラスを拡張できるように保護されています。だから、私たちはすべての数字を可能にするタイプでRestricted
を拡張してみましょう:一見
class Extended : public Restricted {
public:
Extended() { a = -1; }
auto set(int pa) -> void {
a = pa;
}
auto do_something() {
// now a can be negative, so I take that into account
}
};
すべてはokです。 Extended
はRestricted
またはその動作を変更しません。 Restricted
は依然として同じで、負の数を許容する別のタイプを追加するだけです。
Restricted
の私たちの最初の仮定はもはや保持しません。
Restricted r = Extended{};
// or
Extended e;
e.set(-24);
Restricted r = e;
// and then:
r.do_something(); // oups
何かがアップ追加しない:
C++
が警告なしオブジェクトスライスを使用できますので、ユーザは容易に負の数(無効な状態にあるオブジェクト)を保持Restricted
オブジェクトを取得することができ
Restricted
のサブクラスとしてExtended
を作成するのは間違っていましたか?もしそうなら、なぜですか?a
をprotected
と設定するのは間違っていましたか?どうして?protected
は、自分のクラスでの動作の変更を許可すべきではありません。C++
でオブジェクトをスライスするのは間違っていますか?他- 上記のすべてのもの
まあ、それはクラスの設計者次第です。基本クラスにパブリックコピーコンストラクタがある場合は、コピー可能であると考えられます。そうでなければ、保護されたコピーコンストラクタを持っています。 –
あるいは 'a'を' unsigned int'と宣言できます。拡張コンパイル時にコンパイル時の警告が表示されます。 – Ceros
@KerrekSBコピー可能にしたいとしましょう。私はまだ、負の数を保持する基本クラス型のオブジェクトを持つことを期待していません。 – bolov