当我使用winrt :: static_lifetime时,如何获取该类的实例?

时间:2019-05-15 17:50:42

标签: c++-winrt

不久前,我从C ++ / CX切换到C ++ / winrt,但由于要创建单例winrt类,我目前陷入困境。我阅读了有关winrt :: static_lifetime(https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/static-lifetime)的文章,但他们没有提供任何有关如何使用它的代码示例。 所以我的问题是如何通过该方法获取类的实例?

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

winrt::static_lifetime指定工厂是单例,因此您基本上需要将单例实例实现为(现在是单例)工厂的属性。

即:

namespace Foo::implementation {
    struct Foo : FooT<Foo> {
        Foo() {
        }

        static Foo Singleton() {
            auto fooFactory = winrt::make<factory_implementation::Foo>().as<IFooStatics>();
            return fooFactory.Singleton();
        }
    };
}

namespace Foo::factory_implementation {
    // specifies the factory is a singleton
    struct Foo : FooT<Foo, implementation::Foo, winrt::static_lifetime> 
    {
        Foo Singleton() {
            slim_lock_guard lock{ m_lock };
            if (!m_singleton) {
                m_singleton = winrt::make<Foo>();
            }
            return m_singleton;
        }

    private:
        winrt::slim_mutex m_lock;
        Foo m_singleton;
    };
}

那么,与以下类似内容相比,为什么这是首选?

static Foo Singleton() {
    static auto single = winrt::make<Foo>();
    return single;
}

之所以这样做,是因为RoUninitialize之后进程静态可能会被破坏,从而导致崩溃。 winrt :: static_lifetime基本上将工厂放入CoreApplication.Properties中,该工厂在进程进行RoUninitialize之前是安全地未初始化的。基本上出于同样的原因,过去也需要避免将旧的COM对象存储到进程全局变量中。