2

C++ を学習していますが、この演習について質問があります。

#include<iostream>
using namespace std;

class B {
    public:
        int x;
        B(int z=1): x(z) {}
};

class D: public B {
    public:
        int y;
        D(int z=5): B(z-2), y(z) {}
};

void fun(B* a, int size) {
    for(int i=0; i<size; ++i) cout << (*(a+i)).x << " ";
}

int main(){
    fun(new D[4],4); cout << "**1\n";
    B* b = new D[4]; fun(b,4); cout << "**2\n";
    b[0] = D(6); b[1] = D(9); fun(b,4); cout << "**3\n";
    b = new B[4]; b[0] = D(6); b[1] = D(9);
    fun(b,4); cout << "**4\n";
}   

それは印刷します:

3 5 3 5 **1
3 5 3 5 **2
4 7 3 5 **3
4 7 1 1 **4

**1 の前と **2 の前に、3 5 3 5 と出力されるのはなぜですか? 私は 3 3 3 3 と考えていました。**3 の前は 5 7 3 3 と考えていました。**4 の前は 4 7 3 3 と考えていました。

前もって感謝します!

4

2 に答える 2

3

配列をポリモーフィックに扱わないでください。[ 1 ] [ 2 ] ご覧のとおり、未定義の動作が発生します。幸いなことに、間違った結果が表示されただけですが、そのページにはクラッシュを示すコード スニペットがあります。

于 2013-08-11T11:50:59.177 に答える
1

行から出力 3 5 3 5 **1 の最初の行について説明します。

fun(new D[4],4); cout << "**1\n";

メソッド fun は、D のスーパークラスである B* をパラメーターとして受け入れることに注意してください。D オブジェクトの配列を渡します。

さらに、配列内の次のオブジェクトに進むときにメソッド fun でポインター演算を使用していることに注意してください。B には 1 つの変数 (x) と 2 つの変数 (x と y) があるため、B はオブジェクト D の半分のサイズです。オブジェクトは D であり、B ではありません (ただし、B にスライスされますが、連続したメモリに D として格納されます)。 - 配列)、途中まで進んでいます。その結果、実際には値 x (B から) を出力し、次に y の値 (D から) などを出力します。

于 2013-08-11T12:09:06.970 に答える