基本クラスAと派生クラスBの2つのクラスがあり、これを書きます
A obj;
B obj2;
obj = obj2;
代入演算子をまだオーバーライドしていない場合、実際にはどうなるでしょうか? これは obj2 の A 部分を obj にコピーするだけでしょうか? これは適切なのか、それともコンパイラが許すエラーなのか? IS_A 関係は、このステートメントの実行を許可しますか? どんな助けでも大歓迎です。
基本クラスAと派生クラスBの2つのクラスがあり、これを書きます
A obj;
B obj2;
obj = obj2;
代入演算子をまだオーバーライドしていない場合、実際にはどうなるでしょうか? これは obj2 の A 部分を obj にコピーするだけでしょうか? これは適切なのか、それともコンパイラが許すエラーなのか? IS_A 関係は、このステートメントの実行を許可しますか? どんな助けでも大歓迎です。
これは確かに許可されています。A
のサブオブジェクトをobj2
に割り当てobj
ます。
IS-Aの関係により、Aのインスタンスからの割り当てを防ぐことなく、コンパイル時にこれを防ぐことはほとんど不可能です。
obj2の「A」部分を浅くコピーします。
言語の観点からは完全にOKです。
アプリに問題がない場合、それは多くの要因に依存しますが、それが代入演算子をオーバーロードできる理由です。
class Base
{
//Members
};
class Derived1:public Base
{
//Members
};
class Derived2:private Base
{
//Members
};
int main()
{
Base obj1;
Derived1 obj2;
Derived2 obj3;
obj1 = obj2; //Allowed Since Public Inheritance
obj1 = obj3; //Not Allowed, Compiler generates error
}
obj1 = obj2
基本クラスから継承された派生クラス obj2 のメンバーのみが obj1 にコピーされると、派生クラスの残りのメンバーは切り捨てられます。これは単純に、基本クラス obj1 が派生クラスのメンバーを認識していないためです。この現象は と呼ばれObject Slicing
ます。
クラスにヒープへの割り当てが必要なポインター メンバー変数がある場合、obj1 = obj2
が作成されますShallow Copy
。これは、obj1 と obj2 内のポインター メンバー変数が同じヒープ メモリを指すようになることを意味します。では、obj2 が OS によって再利用され、obj1 がまだ使用されている場合はどうなるでしょうか。災害!overloading = operator
そのため、オブジェクトの作成によって浅いコピーを避ける必要がDeep copy
あります。
代入演算子をオーバーロードします。実装では、AパーツのBパーツが割り当てられます... Aに存在するBの値を割り当てようとするまで、コンパイラエラーは生成されません。
A::operator=(const A& value);
実行されます。obj1
に暗黙的にキャスト (static_cast) しconst A&
ます。
だからあなたobj=obj1;
はと同等です
obj = static_cast<const A&>(obj1);
明らかに暗黙的に生成された代入は、 のすべての非静的メンバーを代入しますA
。
これを拒否するには、private/protected 継承を使用します。パブリック継承を使用することにより、タイプのすべてのオブジェクトがB
あらゆる方法でタイプ A のオブジェクトとして合法的に使用される可能性があると主張します。
明示的に宣言することもできます
A& A::operator=( const B& value );
または、定義することもできます
A& A::operator=( const A& value );
ポリモーフィックな方法で動作します。