何时使用winrt::make而非直接调用构造函数?
关于WinRT中winrt::make与直接调用构造函数的疑问
两段等价实现的代码:
第一段代码:
if (!m_mainWindow) { m_mainWindow = winrt::make<App1::implementation::MainWindow>(); } if (!m_mainWindow.Content()) { m_mainWindow.Content(winrt::make<App1::implementation::ShellPage>()); } m_mainWindow.Activate();
第二段代码:
if (!m_mainWindow) { m_mainWindow = App1::MainWindow(); } if (!m_mainWindow.Content()) { m_mainWindow.Content(App1::ShellPage()); } m_mainWindow.Activate();
问题:
是否存在必须使用winrt::make而非直接调用构造函数的理由?微软文档推荐使用winrt::make,但原因是什么?
回答:
你给出的两段代码在功能上确实等价,但微软推荐显式使用winrt::make而非直接调用构造函数,主要有以下几个关键原因:
- 代码清晰性与类型区分:
winrt::make明确标识这是在创建WinRT运行时对象,而非普通C类实例。直接调用构造函数的写法和常规C对象创建一致,容易模糊WinRT对象特殊的引用计数生命周期逻辑。 - 适配私有实现类:WinRT普遍采用Pimpl设计模式,公开的
App1::MainWindow是一个包装类型,真正的实现类App1::implementation::MainWindow通常是私有(仅在实现代码中可见)。直接调用App1::MainWindow()能工作是因为编译器生成了适配代码,但如果实现类完全不对外暴露,这种写法会编译失败;而winrt::make可以直接访问实现类(只要在实现代码范围内)。 - 统一代码范式:WinRT生态中所有组件对象的创建都推荐使用
winrt::make,保持一致的代码风格,避免在不同场景下切换创建方式,降低后续维护成本。 - 规避潜在生命周期风险:WinRT对象基于引用计数管理生命周期,
winrt::make会正确初始化对象的引用计数状态。虽然直接调用构造函数在多数场景下也能正常工作,但显式遵循winrt::make的规范,能确保你严格按照WinRT的对象创建流程操作,减少因误用导致的内存泄漏或悬垂引用问题。
内容的提问来源于stack exchange,提问作者yasar
相关产品推荐
相关产品推荐

