C ++でのオブジェクトスライス
-
23-10-2019 - |
質問
class Base
{
int iBase;
public:
virtual void display()
{
cout<<"I am a Base Class"<<endl;
}
};
class Derived : public Base
{
int iDerived;
public:
Derived()
{
cout<<"In Derived Default Constructor"<<endl;
iDerived=10;
}
void display()
{
cout<<"I am in Derived Class"<<endl;
cout<<"value of iDerived :"<<iDerived<<endl;
iDerived=100;
cout<<"value of iDerived :"<<iDerived<<endl;
}
};
主に:
Base *varBase;
Derived varDerived;
varBase = &varDerived;
varBase->display();
varBase->iDerived=10; // Error: iDerived is not a member of Base: ?????
こんにちは、みんな、
オブジェクトのスライスを理解し、いくつかのサンプルプログラムで試してみようとしています。
私はどこかでポインターの参照で読みますobjcetスライスは起こりません。
しかし、以下の例では、私はそれに気づいています iDerived
からアクセスできません Base pointer(varBase)
, 、しかしから virtual display method of class
現地のディスプレイ範囲にない場合でもアクセスできます。
今私の質問は次のとおりです。
- 仮想関数でのみ等縁元変数にアクセスできるのはなぜですか?これは適切ですか?
- オブジェクトのスライスを避ける方法。
解決
C ++には仮想関数がありますが、仮想データはありません。
以下を追加してシミュレートできます。
class Base {
// What you had before
virtual int getAnInt() const = 0; // =0 means that Derived must implement this
};
class Derived {
// What you had before
virtual int getAnInt() const { return iDerived; }
};
オブジェクトのスライスはまったく関係がなく、例では発生しません。
他のヒント
あなたの例コードにはまったくスライシングが含まれません。あなたがしたことは、基本的な多型を呼び出すことです。宣言することによって Base::display()
なので virtual
そして電話することによって display()
aで Base *
, 、あなたはそれを、メンバー関数を動的に呼び出すように頼みました 実際 指されているオブジェクトのタイプ、それは Derived
. 。のメンバー変数 Derived
の範囲内です Derived::display()
, 、だからそれがそれがコンパイルされて動作する理由です。
ただし、で宣言されたメンバー変数(または関数)のみに直接アクセスできます ベース ポインタから -Base
. 。それが理由です varBase->iDerived
コンパイルしません。
スライスするには、通常、次のものに相当するものが含まれます。
Derived d;
Base b = (Base)d;
aを明示的に割り当て/初期化することにより Base
オブジェクト、すべて Derived
- 特定のメンバーは失われました(つまり、彼らは「スライスされた」)。
このようなものは比較的基本的です。 C ++でまともな本を手に入れることをお勧めします。ここに良いもののリストがあります: 決定的なC ++ブックガイドとリスト.