【问题标题】:Error while implementing a windows runtime interface for local consumption while porting from c++/cx to c++/winrt在从 c++/cx 移植到 c++/winrt 时实现 Windows 运行时接口以供本地使用时出错
【发布时间】:2020-12-28 12:20:10
【问题描述】:

更新

根据 Ryan Shepherd 的回复,我将代码更改为:

class DerivedClass : winrt::implements<DerivedClass, BaseClass> {
public:
DerivedClass(winrt::FrameworkElement& control) : 
5===>implements_type(control) {}

static winrt::com_ptr<DerivedClass> from(winrt::FrameworkElement control) { 
    control ? control.Tag().try_as<SvgCanvasController>() : nullptr;
}
}

现在我得到一个错误:

没有构造函数实例 "winrt::implements::implements [with D=DerivedClass, I=BaseClass]" 匹配参数列表参数类型是:(winrt::Windows:: UI::Xaml::FrameworkElement)。

我确实定义了 BaseClass 构造函数,它接受 &FrameworkElement 作为参数。所以我不确定我得到了这个错误。

原创

我在 C++/CX 中有这个:

ref class DerivedClass sealed : public BaseClass {
public:
explicit DerivedClass(Windows::UI::Xaml::FrameworkElement^ &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::FrameworkElement& control) : BaseClass(control) 
2===>{
}

static DerivedClass from(winrt::FrameworkElement control) { 
    if (control)
 3===>       return control.Tag().try_as<SvgCanvasController>();
    else
 4===>       return nullptr;
}

这里有几个问题我想讨论和理解。如上所述,我收到以下错误:

1

BaseClass 不是 DerivedClass 类的非静态数据成员或基类

2

winrt::implements的默认构造函数不能被引用——它是一个被删除的函数

3

没有合适的用户定义从 winrt::impl::com_ref 到 DerivedClass 的转换

4

不存在从 std::nullptr_t 转换为 DerivedClass 的合适构造函数

希望对这些错误有一些想法。

我知道我创建了一个 DerivedClass 对象

auto obj = winrt::make<DerivedClass>();

问题:

  1. 如何正确编写构造函数?
  2. 如何像在 C++/CX 中那样将参数传递给基类构造函数?
  3. 如何处理 from() 函数定义中的错误。

【问题讨论】:

  • 驱动class 时的默认访问修饰符是private。要么将其设为struct,要么指定您要驾驶publicly。

标签: uwp uwp-xaml c++-cx c++-winrt cppwinrt


【解决方案1】:

关于第一个错误,DerivedClass 不继承自 BaseClass,它继承自 winrt::implements&lt;DerivedClass, BaseClass&gt;,然后派生自 BaseClass。孙子类不能直接初始化它的祖父类——它大部分都通过它的直接基类型。幸运的是,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 const&)
    {}
};

struct DerivedType : implements<DerivedType, BaseType>
{
    explicit DerivedType(FrameworkElement const& arg)
        : implements_type(arg)
    {}
};

int main()
{
    make<DerivedType>(FrameworkElement{ nullptr });
}

这段代码为我编译成功。

其他三个错误是由于您试图直接在堆栈上返回 实现 类型。这些对象是引用计数的,并且必须在堆上分配,由于调用winrt::make,您似乎理解了这一点。但等式的其余部分是,您需要返回winrt::com_ptr&lt;DerivedClass&gt;,而不是返回DerivedClass,结果如下:

static winrt::com_ptr<Derived> from(winrt::FrameworkElement const& arg)
{
  return arg ? arg.Tag().try_as<DerivedClass>() : nullptr;
}

【讨论】:

  • 感谢您的回答。当我使用 implements_type(control) 时,出现以下错误:“没有构造函数实例 winrt::implements::implements [with D=DerivedClass, I=BaseClass]”与参数列表匹配参数类型是:(winrt::Windows::UI::Xaml::FrameworkElement)。我确实定义了 BaseClass 构造函数,它接受 &FrameworkElement 作为参数。所以我不确定我错过了什么。或者如果我的理解仍然缺乏。
  • 我怀疑您的示例比发布的更多。我已经更新了上面的代码以模仿您问题中的代码,并且它为我成功编译。
猜你喜欢
  • 1970-01-01
  • 2020-12-17
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多