Как получить экземпляр класса, когда я использую winrt :: static_lifetime? - PullRequest
1 голос
/ 15 мая 2019

Я недавно перешел с C ++ / CX на C ++ / winrt, и сейчас я застрял, потому что хочу создать синглтон-класс winrt.Я читал о winrt :: static_lifetime (https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/static-lifetime),, но они не предоставляют никакого примера кода о том, как его использовать. Поэтому мой вопрос заключается в том, как получить экземпляр класса с этим?

Заранее спасибо за помощь.

1 Ответ

1 голос
/ 29 мая 2019

winrt::static_lifetime указывает, что фабрика является одноэлементной, поэтому вам необходимо реализовать экземпляр синглтона как свойство фабрики (теперь одноэлементной).

А именно:

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

        static Foo Singleton() {
            auto fooFactory = winrt::make<factory_implementation::Foo>();
            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-объектов в глобалах процессов.

...