Наследование в C ++ / CX не такое же, как наследование в C ++. Это связано с тем, что классы C ++ / CX ref на самом деле являются COM-объектами, которые реализуют наследование посредством различных агрегаций.
Пример, с которым я работал, был
public ref class MyTextBox : public TextBox {
MyTextBox() {};
~MyTextBox() {};
virtual void OnKeyDown(KeyEventArgs^ e) override {
TextBox::OnKeyDown(e);
};
};
, который не будет работать, потому что TextBox :: OnKeyDown () будет эффективно вызывать MyTextBox :: OnKeyDown (). Это связано с тем, как виртуальные методы реализованы в C ++ / CX и COM, подробный обзор можно прочитать здесь .
Visual Studio 11 Developer Preview Solution
Короткая версия заключается в том, что метод OnKeyDown () является частью интерфейса IControlOverrides, реализованного как MyTextBox, так и TextBox, благодаря некоторым хитрым трюкам компилятора. Чтобы получить указатель на интерфейс для реализации TextBox, мы сначала должны запросить его у TextBox - если мы спросим MyTextBox, мы окажемся там, где начали. И поскольку это наследование в COM, а не в C ++, мы делаем это через указатель на объект baseclass вместо this :
virtual void OnKeyDown(KeyEventArgs^ e) override {
struct IControlOverrides^ ico;
HRESULT hr = __cli_baseclass->__cli_QueryInterface(const_cast<class Platform::Guid%>(reinterpret_cast<const class Platform::Guid%>(__uuidof(struct IControlOverrides^))),reinterpret_cast<void**>(&ico));
if (!hr) {
hr = ico->__cli_OnKeyDown(e);
};
};
Visual Studio 11 Beta Solution
Как и во многих других вещах, это было улучшено в бета-версии VS 11. Хотя «__super ::» по-прежнему не будет работать, теперь он работает нормально, просто для явного вызова интерфейса, в котором он определен:
virtual void OnKeyDown(KeyEventArgs^ e) override {
IControlOverrides::OnKeyDown(e);
};
Обозреватель объектов в VS покажет вам, какой интерфейс определен методом OnKeyDown () в (IControlOverrides).
Проблема решена!