1

仮想印刷関数を使用してスーパー クラスを宣言し、子クラスはスーパー クラスを継承します。子クラスのインスタンスを作成し、2 つの異なる方法でスーパー クラスに割り当てました。

#include <iostream>

using namespace std;

class Super
{
public:
    Super(){}
    virtual void print()
    {
    cout << "Super class is printing " << endl;
    }
};

class Child: public Super
{
public:
    Child(){}
    void print()
    {
        cout << "Child class printing" << endl;
    }
};

int main()
{
    Child c;
    Super s = c;
    Super &ss = c;
    s.print(); //prints "Super Class is printing
    ss.print(); //prints "Child Class is printing
    return 0;
}

これら 2 つの印刷呼び出しから同じ出力が得られないのはなぜですか? 参照を追加すると動作がどのように変わりますか?

4

2 に答える 2

2

の動的および静的タイプはsis ですSuperが、割り当て fromは内部からサブオブジェクトcのコピーを作成し、常に として動作します。SupercsSuper

ただし、ssの静的型はSuperですが、その動的型はその初期化 (この場合はChild) に依存するため、仮想ディスパッチはそれに応じて動作します。

この現象を「オブジェクトスライス」と呼びます

于 2013-08-03T18:13:42.553 に答える
1

オブジェクトのスライスの問題:

スーパー クラスを取得してサブクラスの値を代入すると、スーパー クラスの一部であるメンバーのみがコピーされます (デフォルトの代入演算子の動作)。

次の点を考慮してください。

#include <iostream>

using namespace std;

class Super {
public:
   int a;
   Super(): a(0) { }
   Super(int _a): a(_a) { }
   virtual void dump() {
        cout << "A is : " << a << std::endl;
   }
};

class Child: public Super {
public: 
   int b;

   Child(int _a, int _b): b(_b), Super(_a) { } 
   virtual void dump() {
        Super::dump();
        cout << "B is : " << b << std::endl;
   }

};

int main() {
    Child c(5, 10);
    Super s;
    s.dump();  // A is 0
    s = c;
    s.dump();  // A is 5 (but there is no B in s 
               // so calling Child::dump would be nonsensical
}

dumpしたがって、子の値が親に割り当てられている場合、子の呼び出しは無意味であることがわかります。親コンテキストに「b」がないためです。

c = s; のようなステートメントに注意してください。

親子関係は決定論的ですが (Child は Super の型であるため、暗黙の演算子Super& Super::operator=(const Super&)が派生クラスに適用されるため、Childその逆は真ではありません。つまり、次Child& Child::operator=(const Child&)のコンテキストでは意味がありません。Super

参考問題

さて、参照変数とは何かを理解することから混乱が生じます。参照変数は、それが初期化されるものの同義語です。元の変数とまったく同じように参照変数を使用できます。

あなたの場合:

   ss.print(); 

と同じです

   c.print();

" これをより明確に確認するには、次のスニペットを検討してください。

int foo;
int& bar = foo;

// bar is now a reference to foo so the following will sets foo to 67
bar = 67;
std::cout << foo <<std::endl;
于 2013-08-03T18:14:53.423 に答える