Simulating static constructors in C ++?

Anyway, I can change this code example

#include <stdlib.h>
#include <iostream>

class Base {
public:
    Base() {
        if(!m_initialized) {
            static_constructor();
            m_initialized = true;
        }
    }
protected:
    virtual void static_constructor() {
        std::cout << "Base::static_constructor()\n";
    }
private:
    static bool m_initialized;
};

bool Base::m_initialized = false;

class Derived : public Base {
    void static_constructor() {
        std::cout << "Derived::static_constructor()\n";
    }
};

int main(int argc, char** argv) {
    Derived d;
    return(EXIT_SUCCESS);
}

So, is it called instead Derived::static_constructor()? I want to initialize a bunch of static variables, and the most logical place for this is somewhere in the class.

+3
source share
4 answers

I made this decision from Martin V Lowis. The main differences are that it uses multiple inheritance and CRTP:

template<class T>
class StaticInitializer : public T
{
  static bool initialized;
 public:
  StaticInitializer(){
    if(!initialized){
      T::static_constructor();
      initialized=true;
    }
  }
};

template<class T> bool StaticInitializer<T>::initialized;

class Base : public StaticInitializer<Base>
{
public:
  static void static_constructor() {
    std::cout << "Base::static_constructor()\n";
  }
};
static Base _base;

class Derived : public Base, public StaticInitializer<Derived>
{
public:
    static void static_constructor() {
      std::cout << "Derived::static_constructor()\n";
    }
};
static Derived _derived;

Each particular subclass of StaticInitializer gets its own static constructor initialization method, but you retain the advantage of having true inheritance.

+4
source

( )! "" (, , ). ? (Base) Derived. , Derived, , . , , , vtable Derived, Base. , - ​​ , Base() , Derived().

, Open/Closed-princip, , , : " , ". , , . , , , ;)

+5

. , . static, .

#include <iostream>
using namespace std;

template<class T>
class StaticInitializer{
  static bool initialized;
 public:
  StaticInitializer(){
    if(!initialized){
      T::static_constructor();
      initialized=true;
    }
  }
};

template<class T> bool StaticInitializer<T>::initialized;

class Base{
public:
  static void static_constructor() {
    std::cout << "Base::static_constructor()\n";
  }
};
static StaticInitializer<Base> _base;

class Derived{
public:
    static void static_constructor() {
      std::cout << "Derived::static_constructor()\n";
    }
};
static StaticInitializer<Derived> _derived;

int main()
{}
+3

:

#include <cstdlib>
#include <iostream>

class Object {
public:
    Object() {
        std::cout << m_var << std::endl;
    }
private:
    static int m_var, init_var();
};

int Object::init_var() {
    return 5;
}

int Object::m_var = Object::init_var();

int main(int argc, char** argv) {
    Object o;
    return(EXIT_SUCCESS);
}

m_var , .

0

Source: https://habr.com/ru/post/1717089/


All Articles