|
Class constructor |
Top Previous Next |
|
What is translated > Types > Records, Classes, Interfaces > Class > Constructors > Class constructor In Delphi, besides instance constructors, there is a class constructor that runs once per type before the first use of that type, after all involved unit initialization sections. “Use” includes creating an instance, accessing a class member, or querying RTTI. A base type’s class constructor runs before the derived type’s class constructor.
A Delphi class constructor is declared as:
class constructor Create;
C++ has no direct notion of Delphi’s class constructor, and adding a second “static constructor” with the same name as the instance constructor would be ambiguous. Therefore, we translate it to a static function named ClassCreate, invoked through a one-time initializer. class MyType { public: static void EnsureClassInitialized();
protected: static void ClassCreate(); static void RegisterAtExit(); // optional: for a Delphi-like class destructor
private: static std::once_flag m_initFlag; };
// MyType.cpp #include "Mytype.h"
std::once_flag MyType::m_initFlag;
void MyType::EnsureClassInitialized() { std::call_once(m_initFlag, []() { ClassCreate(); RegisterAtExit(); }); }
void MyType::ClassCreate() { // One-time setup; mirrors Delphi "class constructor" ... }
At every public entry point (instance constructors, static methods, and getters for translated “class vars”), call EnsureClassInitialized(). This reproduces Delphi’s “executed before first use” guarantee, and it’s thread-safe thanks to std::call_once.
Inheritance
Delphi’s base-first order is mimicked by calling the base type’s initializer from the derived type’s initializer:
class Base { public: static void EnsureClassInitialized(); protected: static void ClassCreate(); private: static std::once_flag m_init; };
class Derived : public Base { public: static void EnsureClassInitialized(); protected: static void ClassCreate(); private: static std::once_flag m_init; };
// Impl std::once_flag Base::m_init; std::once_flag Derived::m_init;
void Base::EnsureClassInitialized() { call_once(m_init, &Base::ClassCreate); }
void Derived::EnsureClassInitialized() { // Delphi: base class class-ctor runs first Base::EnsureClassInitialized(); call_once(m_init, &Derived::ClassCreate); }
So Base::EnsureClassInitialized() is called at the beginning of Derived::EnsureClassInitialized() before Derived::ClassCreate() runs.
|
|
This page belongs to the Delphi2Cpp Documentation |
Delphi2Cpp home Content |