#uwp #uwp-xaml #c -cx #c -winrt #cppwinrt
#увп #uwp-xaml #c -cx #c -winrt #cppwinrt #uwp #c -cx
Вопрос:
Обновить:
Основываясь на ответе Райана Шепарда, я изменил свой код на:
class DerivedClass : winrt::implements<DerivedClass, BaseClass> {
public:
DerivedClass(winrt::FrameworkElementamp; control) :
5===>implements_type(control) {}
static winrt::com_ptr<DerivedClass> from(winrt::FrameworkElement control) {
control ? control.Tag().try_as<SvgCanvasController>() : nullptr;
}
}
Теперь я получаю сообщение об ошибке:
ни один экземпляр конструктора «winrt::implements<D, I, …>::implements [with D=DerivedClass, I=BaseClass]» не соответствует списку аргументов типы аргументов: (winrt::Windows::UI::Xaml::FrameworkElement).
У меня действительно определен конструктор базового класса, который принимает в качестве аргумента amp;FrameworkElement. Поэтому я не уверен, что получаю эту ошибку.
Оригинал:
У меня было это в C / CX:
ref class DerivedClass sealed : public BaseClass {
public:
explicit DerivedClass(Windows::UI::Xaml::FrameworkElement^ amp;control)
: BaseClass(control) {}
static DerivedClass from(Windows::UI::Xaml::FrameworkElement^ control) {
return control ? dynamic_cast<DerivedClass>(control->Tag) : nullptr;
}
}
когда я пытаюсь преобразовать это в c / winrt
class DerivedClass : winrt::implements<DerivedClass, BaseClass> {
public:
1===>DerivedClass(winrt::FrameworkElementamp; control) : BaseClass(control)
2===>{
}
static DerivedClass from(winrt::FrameworkElement control) {
if (control)
3===> return control.Tag().try_as<SvgCanvasController>();
else
4===> return nullptr;
}
Здесь есть несколько проблем, которые я хочу обсудить и понять. Как написано выше, я получаю следующие ошибки:
1
Базовый класс не является нестатическим элементом данных или базовым классом класса DerivedClass
2
невозможно ссылаться на конструктор winrt по умолчанию::implements<Производный класс, базовый класс> — это удаленная функция
3
Нет подходящего пользовательского преобразования из winrt::impl::com_ref<DerivedClass> в DerivedClass
4
не существует подходящего конструктора для преобразования из std::nullptr_t в DerivedClass
Хотелось бы услышать несколько мыслей по поводу этих ошибок.
Я понимаю, что я создаю объект DerivedClass как
auto obj = winrt::make<DerivedClass>();
Вопросы:
- Как мне правильно написать конструктор?
- Как я могу передать аргумент конструктору базового класса, как я делаю в C / CX?
- Как я могу справиться с ошибками в определении функции from().
Комментарии:
1. Модификатор доступа по умолчанию при управлении
class
являетсяprivate
. Либо сделайте этоstruct
, либо укажите, что вы хотите использоватьpublic
ly.
Ответ №1:
Что касается первой ошибки, DerivedClass
не наследуется от BaseClass
, она наследуется от winrt::implements<DerivedClass, BaseClass>
, которая затем является производной от BaseClass
. Класс grandchild не может напрямую инициализировать своего прародителя — в большинстве случаев он проходит через свой непосредственный базовый тип. К счастью, C / WinRT предоставляет вспомогательный тип в winrt::implements
, поэтому вам не нужно повторять все эти параметры шаблона. Итак, ваш конструктор должен выглядеть следующим образом:
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.UI.Xaml.h>
using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::UI::Xaml;
struct BaseType : implements<BaseType, IInspectable>
{
explicit BaseType(FrameworkElement constamp;)
{}
};
struct DerivedType : implements<DerivedType, BaseType>
{
explicit DerivedType(FrameworkElement constamp; arg)
: implements_type(arg)
{}
};
int main()
{
make<DerivedType>(FrameworkElement{ nullptr });
}
Этот код успешно компилируется для меня.
Остальные три ошибки связаны с тем, что вы пытаетесь вернуть тип реализации непосредственно в стек. Эти объекты подсчитываются по ссылкам и должны быть размещены в куче, что вы, кажется, понимаете из-за вызова winrt::make
. Но остальная часть уравнения заключается в том, что вместо возврата a DerivedClass
вам нужно вернуть winrt::com_ptr<DerivedClass>
, в результате чего получится что-то вроде этого:
static winrt::com_ptr<Derived> from(winrt::FrameworkElement constamp; arg)
{
return arg ? arg.Tag().try_as<DerivedClass>() : nullptr;
}
Комментарии:
1. Спасибо за ответ. когда я использую implements_type(control), я получаю следующую ошибку: «ни один экземпляр конструктора winrt::implements<D, I, …>::implements [с D=DerivedClass, I=BaseClass]» не соответствует списку аргументов. типы аргументов: (winrt::Windows::UI::Xaml::FrameworkElement). У меня действительно определен конструктор базового класса, который принимает в качестве аргумента amp;FrameworkElement. Итак, я не уверен, чего мне не хватает. Или если моего понимания там все еще не хватает.
2. Я подозреваю, что в вашем примере есть нечто большее, чем опубликовано. Я обновил приведенный выше код, чтобы имитировать код в вашем вопросе, и он успешно компилируется для меня.