3
class CBase {
public:
    void print()
    {
        cout<<"In base print func\n";
    };
};

class CDerived: public CBase {
public:
    void print()
    {
        cout<<"In derived print func\n";
    };
};

int main()
{
    CBase b;
    CBase* pb;
    CDerived d;
    CDerived* pd;
    pd->print();
    return 0;
}

CBase上記のコードは正常に実行されますが、クラスでprint関数を作成すると、virtualセグメンテーション違反が発生します。

この背後には、私が気付いていない基本的な論理があると思います。なぜそうなのかコメントをお願いします。

4

1 に答える 1

3
CDerived* pd;
pd->print();

ポインタが初期化されていません->未定義の動作。

あなたが必要です

CDerived* pd = new CDerived;
pd->print();

また、うまく動作しません。むしろ、うまく動作するのは不運です。仮想ディスパッチには仮想テーブルが必要ですが、ポインターが初期化されていないため、仮想テーブルポインターが存在しないため、関数が仮想の場合にクラッシュします。

仮想でない場合でも、未定義の動作ですが、メンバーを使用しないため、クラッシュしません。

これを証明するには、次のことを試してください。

class CBase {
public:
    int y;
    void print()
    {
        cout<<"In base print func\n" << y;
    };
};

class CDerived: public CBase {
public:
    int x;
    void print()
    {
        cout<<"In derived print func\n" << x;
    };
};

関数がそうでなくてもクラッシュしますvirtual

于 2012-05-09T20:59:09.003 に答える