私は次のような本を読んでいます。
引数を送信する関数のパラメーターの型が抽象基本クラス (ABC) である場合、値渡しは機能しません。参照によって引数 (派生クラス) を渡す必要があります。
私の質問は次のとおりです。
派生クラスの引数を値で渡せないのはなぜですか?
それを参照する必要があるC ++の「内部」のものはありますか?
これは動的バインディングの仕組みと関係がありますか?
私は次のような本を読んでいます。
引数を送信する関数のパラメーターの型が抽象基本クラス (ABC) である場合、値渡しは機能しません。参照によって引数 (派生クラス) を渡す必要があります。
私の質問は次のとおりです。
派生クラスの引数を値で渡せないのはなぜですか?
それを参照する必要があるC ++の「内部」のものはありますか?
これは動的バインディングの仕組みと関係がありますか?
これは、オブジェクトのスライシングによるものです。値によって受け取られた抽象クラスは、渡されたオブジェクトのコピーを受け取ります。したがって、派生データ メンバーはそこから切り離され、オブジェクトが使用できなくなります。
参照渡しの場合、派生クラスのメンバーである既存のオブジェクトのアドレスを渡し、そのすべてのデータ メンバーを含めます。これは C++ に固有のものではありません。これは、一般的に値渡しの特性です。
動的バインディングは、スライスされたインスタンスが完全なインスタンスであるかのように呼び出しを受信できないように実装されています。vtableポインターは、呼び出しを抽象基本クラスのメンバー関数にディスパッチするように調整されます。
派生クラスの引数を値で渡せないのはなぜですか?
簡単に言えば、次のような関数があるとします。
void foo(T t); // Takes a T by value
そして、あなたはそれをこのように呼びます(何であれv
):
foo(v);
何が起こるかというと、あたかもあなたがやっているかのように、パラメータが引数からコピー初期化された新しいt
オブジェクトを表すということです:v
T t = v;
が抽象の場合T
、(定義により) 抽象クラスをインスタンス化できないため、上記は違法です。したがって、 のパラメーターをfoo()
その引数からコピー初期化することはできません。
それを参照する必要があるC ++の「内部」のものはありますか?
そんな感じ。C++ の動的ポリモーフィズムは、参照とポインターを介してのみ機能します。派生クラスのオブジェクトを基本クラスのオブジェクトに割り当てようとすると、オブジェクトのスライスが発生します。
派生クラスを値で渡すことができます。抽象クラスをインスタンス化する方法がないため、抽象基本クラスを引数として値で渡すことはできません。
一般に、オブジェクトをスライスしないように、参照またはポインターで渡します。ここに良い答えがあります:オブジェクトのスライスとは何ですか?
オブジェクトを値で受け取る場合、その動的 (「実際の」型) 型は静的型です。動的型が抽象型の変数を持つことはできません。どのように構築しても構いません。