7

重複の可能性:
仮想関数オブジェクトのスライス

考えてみましょう:

#include <vector>
#include <iostream>
using namespace std;

struct A {
    virtual void do_it() { cout << "A" << endl; } 
};

struct B : public A {
    virtual void do_it()  { cout << "B" << endl; } 
};

int main() {
    vector<A> v;
    v.push_back(B());
    v[0].do_it(); // output is A
}

どの関数が呼び出されますか?基本的に、スライスが存在しない場合、ポインターなしでポリモーフィズムを使用することは可能ですか?

4

5 に答える 5

15

いいえ、ポインタなしでは不可能です。

オブジェクトを作成してB、を含むベクターにプッシュすると、オブジェクトAがコピーされ(のコピーコンストラクターに送信されA)、のインスタンスがAベクターに追加されます。つまり、オブジェクトはスライスされます。

このコードを考えると:

struct A {
        virtual void d() { 
            std::cout << "Hello A" << std::endl; 
        } 
};

struct B : public A {
        virtual void d() { 
            std::cout << "Hello B" << std::endl; 
        } 
};

int main() {
        std::vector<A> v;
        v.push_back(B());
        v[0].d();
}

出力は次のようになります。

Hello A
于 2012-07-26T14:07:13.737 に答える
6

問題は、あなたの例では実際にスライスがあるということです。使用するpush_backことは、どういうわけか次と同等です。

A array[N];
array[last++] = B();

2行目は、スライスがある場所です。配列内の各位置は、型からのオブジェクトを保持できますが、型からのオブジェクトは保持できAないためBです。

ポインタを使用してこの問題を解決し、vとして定義することができますstd::vector<A*> v。おそらくより良いのは、スマートポインター(C ++ 11に存在するものまたはBoostに存在するもののいずれか)を使用することです。

于 2012-07-26T14:07:02.913 に答える
5

ポリモーフィズムは、ポインター/参照なしでC ++で機能しますか?

はいといいえ。

動的ポリモーフィズムは、ポインターまたは参照の静的型がそれが参照するオブジェクトの動的型と異なる可能性がある場合にC ++で機能し、動作は動的型に基づいて選択されます。オブジェクト自体には1つのタイプしかないため、これにはポインターまたは参照が必要です。

テンプレートを使用する静的ポリモーフィズムは、オブジェクトで完全に機能しますが、別のクラスの問題を解決します。あなたの例では、オブジェクトの実行時型に基づいて動作を選択するために、動的ポリモーフィズムが必要です。

どの関数が呼び出されますか?

ベクトルにはタイプのオブジェクトが含まれているAため、A::do_it()と呼ばれます。オブジェクトは、タイプのオブジェクトをスライスすることによって作成されたことを認識していませんB

基本的に、スライスが存在しない場合、ポインターなしでポリモーフィズムを使用することは可能ですか?

派生クラスオブジェクトから基本クラスオブジェクトを作成する場合、スライスは常に存在します。それがスライスの定義です。

于 2012-07-26T14:26:22.957 に答える
4

ポリモーフィズムは、ポインター/参照なしでC ++で機能しますか?

はい。静的ポリモーフィズムを参照してください。

あなたの場合、基本関数が呼び出されますが、ポリモーフィズムが機能しないと言うのは間違っています。ポリモーフィズムは機能することが保証されています、それはあなたがそれを利用していないということだけです。あなたが持っているのは基本的にAオブジェクトのコレクションです。

于 2012-07-26T14:26:40.893 に答える
0

sizeof(parent)は必ずしもsizeof(child)と等しいとは限らないため、これは機能しません。

于 2012-07-26T14:01:32.250 に答える