Почему static_cast (* this) в базовый класс создает временную копию?
Я читаю Effective С++ и наткнулся на этот пример:
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
...
};
В книге говорится:
Что бы вы не ожидали, так это то, что он не вызывает эту функцию для текущего объекта! Вместо этого cast создает новую временную копию части базового класса * this, а затем вызывает onResize на копии!
Почему static_cast (выше код) создает новую копию? Почему бы просто не просто использовать базовый класс объекта?
Ответы
Ответ 1
Потому что этот код просит создать новый объект. Этот код хочет сделать объект Window
из *this
- это можно сделать с помощью конструктора copy Window
.
Вместо этого вы хотите:
static_cast<Window&>(*this).onResize();
// ^
// note the &
Это означает, что я хочу сделать Window&
из *this
- который является неявным преобразованием из производного класса reference (*this
является SpecialWindow&
) до ссылки Window&
.
Однако лучше просто вызвать определенную версию функции-члена onResize()
, которую вы хотите вызвать:
Window::onResize(); // equivalent to this->Window::onResize();
Ответ 2
Это потому, что код отличает значение Window
вместо ссылки Window&
. Согласно стандарту, эта форма кастинга эквивалентна вызову (С++ 11 §5.2.9/4 = С++ 03 §5.2.9/2)
Window __t (*this);
__t.onResize();
который вызывает конструктор-копию Window
и выполняет onResize в этой копии.
(Правильный способ вызова метода суперкласса
Window::onResize();
)
Ответ 3
Поскольку вы выполняете фактический объект, а не указатель или ссылку.
Точно так же при нажатии double
на int
создается новый int
- не повторное использование части double
.
Ответ 4
Контрастность:
static_cast<Window>(*this)
с:
static_cast<Window&>(*this)
Один вызывает конструктор копирования, другой - нет. Это помогает?