c++delphifactoryclass-reference

How would I translate the following "class reference" mechanism from Delphi to C++11?


I've used C++ for a while and one thing which occasionally bugs me is that I haven't yet been able to figure out how to do this Delphi Factory construct in C++.

The key part that I can't figure out is how to pass a reference to a class type in C++. In Delphi, we have "TClass" type. Variables of this type are a reference to some class. We can restrict the classes that a class reference can refer to using the class of MyClass syntax to define a new class reference type.

Note that the term "Delphi class reference" =/= "C++ instance of a class"

For those unfamiliar with Pascal, variables are declared variable: type rather than the C-style type variable. Similarly, a function's return type appears after the parameter list and name.

I've condensed the syntax in the following example to make it less boilerplate-y, so apologies to Delphi devs for the terrible formatting. The key parts are described in comments.

program demo;

{$APPTYPE CONSOLE}

// declarations

type

  Base = class
  public constructor Create(name: string); virtual;
  end;

  // Class reference which refers to Base and its descendants
  BaseClass = class of Base;

  ChildA = class(Base)
  public constructor Create(name: string); override;
  end;

  ChildB = class(Base)
  public constructor Create(name: string); override;
  end;

// implementation

constructor Base.Create(name: string);
begin
  WriteLn('Base says hi to ' + name);
end;

constructor ChildA.Create(name: string);
begin
  inherited Create(name);
  WriteLn('ChildA says hi to ' + name);
end;

constructor ChildB.Create(name: string);
begin
  WriteLn('ChildB says hi to ' + name);
end;

// *** THIS IS THE BIT THAT I'M INTERESTED IN ***
// The function doesn't know at compile time exactly what class it is being
// asked to construct.  The compiler knows that it is or inherits from Base.
// I can't find any kind of "class reference" in C++.
function ConstructSomething(ClassType: BaseClass; name: string): Base;
begin
  Result := ClassType.Create(name);
end;

// Equivalent to "main()" in C
begin

  // Pass references to a class to the ConstructSomething function
  ConstructSomething(Base, 'Mark');
  WriteLn('');

  ConstructSomething(ChildA, 'Mark');
  WriteLn('');

  ConstructSomething(ChildB, 'Mark');
  WriteLn('');

end.

Output:

Base says hi to Mark

Base says hi to Mark
ChildA says hi to Mark

ChildB says hi to Mark

Note that when a reference to a child class is passed then the child class is created. Not calling the base constructor in ChildB is intentional in this demo, to make the "class reference" concept slightly more obvious.


Solution

  • The closest you can get is using a template function

    template<typename ClassType>
    Base* ConstructSomething(string name)
    {
       return new ClassType(name);
    }
    
    int main()
    {
        ConstructSomething<Base>("Mark");
        ConstructSomething<ChildA>("Mark");
    }
    

    but ClassType can't be selected at runtime - it must be known during compilation.