2

派生仮想関数を呼び出すために、基底クラス オブジェクトが参照である必要があるのはなぜですか?

   #include<iostream>
    using namespace std;

    class A {

    public:
        virtual void print() { cout << "Hello 1" << endl; }

    };

    class B : public A {

    public:
        int x;
        void print() { cout << "Hello " << x << endl; }

    };

    void main(){

        B obj1;
        A &obj2 = obj1;
        A obj3 = obj1; // Why it is different from obj2

        obj1.x = 2;

        obj1.print();
        obj2.print();
        obj3.print(); // ?

    }
4

2 に答える 2

5

派生オブジェクトを基本変数に割り当てると、基本クラスのインスタンスに「スライス」されます。それはもはや派生物のインスタンスではありません。これが必要なのは、基本変数には基本クラスのインスタンス用に予約された十分なスペースしかないためです。追加データを含む派生クラスのインスタンスは適合しません。

参照を使用すると、オブジェクトを小さなスペースにコピーする必要がないため、スライスは発生しません。

于 2012-04-26T01:12:12.320 に答える
3
A obj3 = obj1; // Why it is different from obj2

をコピーして obj3 を構築します。この場合、obj1 は A 型にアップキャストされ、obj3 は obj1 の「A」パラメーターから構築されます。この現象はスライシングとして知られています。

A &obj2 = obj1;

この行は、参照 obj2 を obj1 のインスタンスにバインドします。obj2 をポイントすることで、obj1 を「A」にアップキャストしました。C++ では、参照は実際には単なるエイリアスであることに注意してください。obj1 に別の名前を付けましたが、その名前は基本クラスの型にバインドされています。

したがってA obj3、スタック上に新しいオブジェクトを割り当てて構築し、A &obj2既存のものの参照/エイリアスを作成するだけです。

于 2012-04-26T01:11:27.617 に答える