Почему static_cast (* this) для базового класса создает временную копию? - PullRequest
19 голосов
/ 31 января 2012

Я читаю Эффективный 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 ]

30 голосов
/ 31 января 2012

Поскольку этот код просит создать новый объект.Этот код хочет создать объект Window из *this - что можно сделать с помощью конструктора копирования из Window.

Вместо этого вам нужно:

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

Это означает, что я хочу сделать Window& из *this - что является неявным преобразованием из производный класс ' ссылка (*this - SpecialWindow&) - ссылка Window&.

Однако лучше просто вызвать конкретную версию функции-члена onResize(), которую вы хотите вызвать:

Window::onResize(); // equivalent to this->Window::onResize();
8 голосов
/ 31 января 2012

Это потому, что код приводится к значению Window вместо ссылки Window&. Согласно стандарту, эта форма приведения эквивалентна вызову (C ++ 11 §5.2.9 / 4 = C ++ 03 §5.2.9 / 2)

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

, который вызывает конструктор копирования Window и выполняет onResize для этой копии.

(Правильный способ вызова метода суперкласса -

Window::onResize();

)

2 голосов
/ 31 января 2012

Потому что вы приводите реальный объект, а не указатель или ссылку.Это точно так же, как приведение double к int создает новые int - без повторного использования части double.

1 голос
/ 31 января 2012

Контрастность:

static_cast<Window>(*this)

с:

static_cast<Window&>(*this)

Один вызывает конструктор копирования, другой - нет. Это помогает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...