1

I have a C++/WinRT base class that I need to subclass. My problem is that I don't manage to call the base class's protected constructor from the subclass.

That base class is defined in MIDL as follows:

namespace My.Custom.WindowsRuntimeComponent
{
  unsealed runtimeclass BaseClass : Windows.UI.Xaml.Controls.SwapChainPanel
  {
  }
}

From it, the following header and implementation is created:

#pragma once

#include <DirectXMath.h>
#include "BaseClass.g.h"

namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
  struct BaseClass : BaseClassT<BaseClass>
  {
  protected:
    BaseClass();
    ::DirectX::XMFLOAT3 ProtectedMethod();
  };
}
#include "pch.h"
#include "BaseClass.h"
#include "BaseClass.g.cpp"

namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
  BaseClass::BaseClass()
  {
    // Important stuff happening here
  }

  ::DirectX::XMFLOAT3 BaseClass::ProtectedMethod()
  {
    return ::DirectX::XMFLOAT3();
  }
}

The subclass's MIDL, header and implementation are defined as follows:

import "BaseClass.idl";

namespace My.Custom.WindowsRuntimeComponent
{
  runtimeclass SubClass : BaseClass
  {
    SubClass();
    void UseProtectedMethod();
  }
}
#pragma once

#include "BaseClass.h"
#include "SubClass.g.h"

namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
  struct SubClass : SubClassT<SubClass, My::Custom::WindowsRuntimeComponent::implementation::BaseClass>
  {
    SubClass();
    void UseProtectedMethod();
  };
}

namespace winrt::My::Custom::WindowsRuntimeComponent::factory_implementation
{
  struct SubClass : SubClassT<SubClass, implementation::SubClass>
  {
  };
}
#include "pch.h"
#include "SubClass.h"
#include "SubClass.g.cpp"

namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
  SubClass::SubClass()
  {
  }

  void SubClass::UseProtectedMethod()
  {
    ::DirectX::XMFLOAT3 value = ProtectedMethod();
  }
}

The above example compiles. However, if I attempt to call the protected base class constructor from the initializer list of the subclass as shown below I receive a compiler error.

#include "pch.h"
#include "SubClass.h"
#include "SubClass.g.cpp"

namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
  SubClass::SubClass() : BaseClass() // This line does not compile
  {
  }

  void SubClass::UseProtectedMethod()
  {
    ::DirectX::XMFLOAT3 value = ProtectedMethod();
  }
}

The compiler error is as follows: error C2614: 'winrt::My::Custom::WindowsRuntimeComponent::implementation::SubClass': illegal member initialization: 'BaseClass' is not a base or member

Both in the MIDL and the header of SubClass I specify that it inherits from BaseClass so it is unclear to me why the compiler emits that error.

I could work around that problem, I guess, but I'm curious about what exactly is going on here. Any hints?

ackh
  • 1,648
  • 2
  • 18
  • 36
  • Again, IDL is for describing your **public** API. This issue, like your previous issue, is a result of trying to describe implementation details in IDL. – IInspectable Dec 06 '20 at 09:24
  • Has your problem been resolved? If the problem is not resolved, please feel free and contact us. – YanGu Dec 22 '20 at 06:52
  • I ran into the same issue: The constructor of a C++/WinRT sub-class can't call the constructor of it's parent class from the sub-class' initializer list. I get the errors, "E0293 indirect nonvirtual base class is not allowed" and " illegal member initialization: '[my base class name]' is not a base or member." Outside avoiding polymorphism in a WinRT class, is there a workaround for this? – Escovado Dec 30 '20 at 15:21

1 Answers1

0

The SubClass in the winrt::... namespace derives from SubClassT<...>, not from SubClass.
The SubClass that is outside the winrt:: namespace derives from BaseClass, but thats a different one. Your naming is easy to get lost in.

Aganju
  • 6,295
  • 1
  • 12
  • 23
  • 1
    I'm confused by the naming myself. But I can only choose the overall namespace and the class names, the rest gets generated by C++/WinRT. My understanding is that because `SubClass` inherits from `SubClassT` it should be a subclass of `BaseClass`. But being unable to access `BaseClass`'s constructor indicates otherwise. – ackh Dec 05 '20 at 22:06