1

次のサンプルコードを検討してください。

#include <iostream>

using namespace std;

class base
{

   public:
       void func()
      {
         cout << "base::func()" << endl;
      }

};

class derived : public base
{
   public:
       void func()
      {
         cout << "derived::func()" << endl;
      }

};

void dummy(base *bptr)
{
  derived *dptr = static_cast<derived*> (bptr);
  dptr->func();
}

int main()
{
   base bob1;
   derived dob1;

   dummy(&dob1); //Line1
   dummy(&bob1); //Line2
}

dummy1行目では、派生クラスオブジェクトのアドレスを、基本クラスオブジェクトへのポインタを受け取る関数に渡しています。したがって、static_cast関数内dummyは安全です。

Line2では、基本クラスオブジェクトのアドレスを関数に渡しています。したがって、static_cast関数内dummyは安全ではありません。

しかし、コードを実行すると、プログラムは正常に動作します。not safe一言で言えば、プログラムは実行時にクラッシュするはずだと思いました。しかし、クラッシュは発生しませんでした。

これが私が得た出力です。

derived::func()
derived::func()

プログラムが実行時にクラッシュしなかった理由は何ですか?

4

2 に答える 2

10

未定義の動作は何かが起こる可能性があることを意味するため、必ずしもクラッシュする必要はありません。

私が見たほとんどのコンパイラではvirtual、ポインタのクラスメンバーにアクセスしない非メソッドの呼び出しは機能しNULLますが、未定義のままです。

于 2012-07-18T09:18:10.617 に答える
6

C ++のコアコンセプトの1つは、未定義動作です。キャストされたタイプのオブジェクトを指さないポインタを静的にキャストするなど、未定義の動作をもたらす操作を実行すると、プログラムの動作は文字通り未定義になります。標準では特定の動作は定義されていません。プラットフォームは特定のことを行う必要はありません。プラットフォームが示す動作は、標準に従って問題ありません。

この未定義の動作には、通常の動作のように見えることをサイレントに実行することが含まれます。セグメンテーション違反やその他の診断の保証はありません。

于 2012-07-18T09:22:03.287 に答える