25

私はEffective C++を読んでいて、この例に出くわしました:

class Window {                                // base class
public:
  virtual void onResize() { ... }             // base onResize impl
  ...
};

class SpecialWindow: public Window {          // derived class
public:
  virtual void onResize() {                   // derived onResize impl;
    static_cast<Window>(*this).onResize();    // cast *this to Window,
                                              // then call its onResize;
                                              // this doesn't work!

    ...                                       // do SpecialWindow-
  }                                           // specific stuff

  ...

};

本は言う:

あなたが予期しないかもしれないことは、現在のオブジェクトでその関数を呼び出さないことです! 代わりに、キャストは *this の基本クラス部分の新しい一時的なコピーを作成し、そのコピーに対して onResize を呼び出します!

static_cast (上記のコード) が新しいコピーを作成するのはなぜですか? オブジェクトの基本クラス部分だけを使用しないのはなぜですか?

4

4 に答える 4

33

このコードは新しいオブジェクトの作成を要求するためです。Windowこのコードは からオブジェクトを作成しようとしています*this— これは のコピー コンストラクターを使用して行うことができますWindow

代わりにこれが必要です:

static_cast<Window&>(*this).onResize(); 
//                ^
//                note the &

これは、派生クラスの参照( is a ) から参照への暗黙的な変換であるWindow&fromを作成したいことを意味します。*this*thisSpecialWindow&Window&

ただし、呼び出したいメンバー関数の特定のバージョンを呼び出すことをお勧めします。 onResize()

Window::onResize(); // equivalent to this->Window::onResize();
于 2012-01-31T18:27:05.967 に答える
8

これは、コードがWindow参照ではなく値にキャストされているためWindow&です。標準によれば、この形式のキャストは呼び出しと同等です (C++11 §5.2.9/4 = C++03 §5.2.9/2)。

Window __t (*this);
__t.onResize();

のコピー コンストラクターを呼び出し、そのコピーWindowに対して onResize を実行します。

(スーパークラスのメソッドを呼び出す正しい方法は、

Window::onResize();

)

于 2012-01-31T18:28:18.220 に答える
2

ポインターや参照ではなく、実際のオブジェクトをキャストしているためです。の部分を再利用するのではなく、newdoubleを作成するためにキャストするのとまったく同じ方法です。intintdouble

于 2012-01-31T18:27:23.663 に答える
1

対比:

static_cast<Window>(*this)

と:

static_cast<Window&>(*this)

1つはコピーコンストラクターを呼び出し、もう1つは呼び出しません。それは役に立ちますか?

于 2012-01-31T18:31:33.910 に答える