C++/WinRT implementation inheritance: Notes on winrt::implements, part 4
Simple inheritance of a self-contained implements. The post C++/WinRT implementation inheritance: Notes on winrt::implements, part 4 appeared first on The Old New Thing.

Last time, we figured out the rules for inheriting winrt::
in C++/WinRT runtime class implementations: You can use winrt::
in your class hierarchy, as long as you use single inheritance for the winrt::
part. You are not allowed to derive multiply from two different winrt::
base classes.
One case of this is a base class that is configured at construction.
struct StringableInt32 : winrt::implements{ StringableInt32(int value) : m_value(value) {} winrt::hstring ToString() { return winrt::to_hstring(m_value); } private: int m_value; };
We can use this by itself:
auto o = winrt::make(42);
But we can also tell the implements
template that we would like to derive from it.
struct Derived : winrt::implements{ Derived() : StringableInt32(42) {} };
Unfortunately, this doesn’t work because StringableInt32
is an indirect base class, and you can initialize only direct base classes in the constructor. So how do you initialize the StringableInt32
?
The answer can be found by looking at the definition of winrt::
.
templatestruct implements : impl::producers , impl::base_implements ::type { protected: using base_type = typename impl::base_implements ::type; using root_implements_type = typename base_type::root_implements_type; using is_factory = typename root_implements_type::is_factory; using base_type::base_type;
We saw last time that base_
looks for the template parameter that is itself derived from implements
, and makes its type
member type be that template parameter. We define base_
to be that type, which in our case is StringableInt32
.
The using base_type::
imports the constructors of base_type
as constructors of implements
. And for us, this means that we can use the StringableInt32(int value)
constructor as if it were a constructor of implements
.
struct Derived : winrt::implements{ Derived() : implements(42) {} };
The base class can expose other methods to the derived class in the usual way.
struct StringableInt32 : winrt::implements{ StringableInt32(int value) : m_value(value) {} winrt::hstring ToString() { return winrt::to_hstring(m_value); } void set_value(int value) { m_value = value; } private: int m_value; };
struct Derived : winrt::implements{ Derived() : implements(42) {} void Reset() { set_value(0); } };
Okay, so this works for base classes that can fully implement an interface. But what if the base class wants to delegate part of its implementation to the derived class? We’ll look at that next time.
The post C++/WinRT implementation inheritance: Notes on winrt::implements
, part 4 appeared first on The Old New Thing.