technodesigner

Digital design

Olivier Dewit
C++/CX inheritance introduction

C++/CX inheritance introduction

C++/CX is an extension of C++ language designed to use the Windows Runtime (WinRT) to build Windows Store applications, or reusable components for the different supported languages: JavaScript, NET (C#, VB.NET, etc.) and C++.

WinRT is a native API that uses a simplified version of the COM technology. This technology is based on interfaces, and does not support by default class inheritance, except for XAML classes. Therefore, this feature applies to C++/CX language in which we should favor the use of interfaces, except for some XAML use cases.

A C++/CX exposed class, that is intended to be used by a client application in one of the supported languages, must be declared sealed. This prevents its derivation by the client code.

// Vehicle.h
#pragma once
#include "pch.h"
namespace CxSandbox
{	
 public ref class Vehicle sealed
 {
 public:
  Vehicle();
 };
}

The C++/CX class inheritance is possible provided that the C++/CX ancestors classes :

Thus, we can create a Car class inherited from the Vehicle class as follows :

// Vehicle.h
#pragma once
#include "pch.h"
namespace CxSandbox
{
  public ref class Vehicle : Windows::UI::Xaml::DependencyObject
  {
  internal:
    Vehicle();
  };
}
// Car.h
#pragma once
#include "pch.h"
#include "vehicle.h"
namespace CxSandbox
{
  public ref class Car sealed : CxSandbox::Vehicle
  {
  public:
    Car();
  };
}

Vehicle inheritance

Inherit from SurfaceImageSource

XAML interoperability with DirectX can be done with the SurfaceImageSource class (Windows::UI::Xaml::Media::Imaging::SurfaceImageSource), which represents a DirectX drawing surface, and which is usable as a brush at the XAML level.

We can apply the technique presented above to define a brush inherited from SurfaceImageSource, itself expected to be derived:

// DxBrushBase.h
#pragma once
#include "pch.h"
namespace CxSandbox
{
  public ref class DxBrushBase : Windows::UI::Xaml::Media::Imaging::SurfaceImageSource
  {
    internal:
      DxBrushBase(int pixelWidth, int pixelHeight);
  };
}

But a C2512 compilation error occurs: 'Windows::UI::Xaml::Media::Imaging::SurfaceImageSource::SurfaceImageSource' : no appropriate default constructor available.

Indeed, the constructor of DxBrushBase implicitly invokes the default constructor (that is with no arguments) of the ancestor class. However, both SurfaceImageSource constructors take arguments, cf. documentation .

The solution consists in chaining constructor calls, passing the appropriate arguments:

// DxBrushBase.cpp
#include "pch.h"
#include "DxBrushBase.h"
using namespace CxSandbox;
DxBrushBase::DxBrushBase(int pixelWidth, int pixelHeight) : Windows::UI::Xaml::Media::Imaging::SurfaceImageSource(pixelWidth, pixelHeight)
{
  //...
}

Our DxBrushBase class, which does not declare a default constructor, in turn, can be derived as a DxBrush class using the same technique:

// DxBrush.h
#pragma once
#include "pch.h"
#include "DxBrushBase.h"
namespace CxSandbox
{
  public ref class DxBrush sealed : DxBrushBase
  {
    public:
      DxBrush(int pixelWidth, int pixelHeight);
  };
}
// DxBrush.cpp
#include "pch.h"
#include "DxBrush.h"
using namespace CxSandbox;
DxBrush::DxBrush(int pixelWidth, int pixelHeight) : DxBrushBase(pixelWidth, pixelHeight)
{
  //...
}


Powered by the Perspective WebApp - © Olivier Dewit - Lyon, Paris, France - Legal informations