Apr 1, 2014

[c++11] Zero Initialisation for Classes

Devils are in the details :
  • With default constructor, it will initialize the integrals iff it's called by new T(); 
  • If it's user defined constructor, but without explicitly initialize integrals, even called by new T();
    the integrals will not be initialized as integrals();
  • If it's been called by new T;
    no matter user define or default constructor, non of the integrals will be initialized.
Zero Initialisation for Classes
default initialization
zero initialization
value initialization


#include <iostream>
using namespace std;

class Base
{
public:
Base(){cout << "ha" << endl;}
virtual ~ Base(){cout << "base destroctor" << endl;}
};

class cInitialisationReporter : public Base
{
  int i;
public:
  virtual ~cInitialisationReporter()
  {
      std::cout << "cInitialisationReporter::i is " << i << '\n';
  }
};


class cInitialisationReporter2: public Base
{
  int i;
public:
  cInitialisationReporter2() {}
  virtual ~cInitialisationReporter2()
  {
      std::cout << "cInitialisationReporter2::i is " << i << '\n';
  }
};


class cInitialisationReporter3: public Base
{
  int i;
public:
  cInitialisationReporter3()=default;
  virtual ~cInitialisationReporter3()
  {
      std::cout << "cInitialisationReporter3::i is " << i << '\n';
  }
};

template <class T> void
SetMemAndPlacementConstruct_ZeroInitialisation()
{
  T* allocated = static_cast<T*>(malloc(sizeof(T)));
  signed char* asCharPtr = reinterpret_cast<signed char*>(allocated);
  for(int i = 0; i != sizeof(T); ++i)
  {
      asCharPtr[i] = -1;
  }
  new((void*)allocated) T();
  allocated->~T();
}


template <class T> void
SetMemAndPlacementConstruct_DefaultInitialisation()
{
  T* allocated = static_cast<T*>(malloc(sizeof(T)));
  signed char* asCharPtr = reinterpret_cast<signed char*>(allocated);
  for(int i = 0; i != sizeof(T); ++i)
  {
      asCharPtr[i] = -1;
  }
  new((void*)allocated) T;
  allocated->~T();
}

int
main(int argc, char* argv[])
{
  SetMemAndPlacementConstruct_ZeroInitialisation<cInitialisationReporter>();
  SetMemAndPlacementConstruct_ZeroInitialisation<cInitialisationReporter2>();
  SetMemAndPlacementConstruct_ZeroInitialisation<cInitialisationReporter3>();
  SetMemAndPlacementConstruct_DefaultInitialisation<cInitialisationReporter>();
  SetMemAndPlacementConstruct_DefaultInitialisation<cInitialisationReporter2>();
  SetMemAndPlacementConstruct_DefaultInitialisation<cInitialisationReporter3>();
  return 0;
}
Output:
clang++ -std=c++1y -O3 main.cpp && ./a.out
ha
cInitialisationReporter::i is 0
base destroctor
ha
cInitialisationReporter2::i is -1
base destroctor
ha
cInitialisationReporter3::i is 0
base destroctor
ha
cInitialisationReporter::i is -1
base destroctor
ha
cInitialisationReporter2::i is -1
base destroctor
ha
cInitialisationReporter3::i is -1
base destroctor

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.