Showing posts with label cpp_constructor. Show all posts
Showing posts with label cpp_constructor. Show all posts

Apr 12, 2022

[C++] noexcept constructor

Reference:

Using noexcept as operator and making constructor as noexcept.

e.g.
template<typename T>
struct Holder
{
    T value;

template<typename... Args>
    Holder(Args&&... args)
        noexcept(noexcept(T(std::forward<Args>(args)...))) :
        value(std::forward<Args>(args)...) {}
};

Jun 21, 2018

[C++] data member with same symbol name as user declared constructor

http://eel.is/c++draft/class.mem#20

In addition, if class T has a user-declared constructor, every non-static data member of class T shall have a name different from T.


i.e
struct foo { 
  ~foo(); 
  int foo;  // OK
};

struct bar { 
  bar(); 
  int bar;  // Error
};

Mar 21, 2018

[C++] volatile struct type instance copy

volatile struct = struct not possible, why?



This is ill-formed because FOO has an implicit copy constructor defined as: FOO(FOO const&);


And you write FOO test = foo; with foo of type volatile FOO, invoking: FOO(volatile FOO const&);


But references-to-volatile to references-to-non-volatile implicit conversion is ill-formed.

From here, two solutions emerge:
  • don't make volatile to non-volatile conversions;
  • define a suited copy constructor or copy the object members "manually";
  • const_cast can remove the volatile qualifier, but this is undefined behavior to use that if your underlying object is effectively volatile.

Could I possibly use memcopy() for that?

No you cannot, memcpy is incompatible with volatile objects: thre is no overload of it which takes pointers-to-volatile, and there is nothing you can do without invoking undefined behavior.

So, as a conclusion, your best shot if you cannot add a constructor to FOO is to define:
FOO FOO_copy(FOO volatile const& other) { 

FOO result; 

result.a = other.a; 

result.b = other.b;

result.c = other.c;

return result; }

Aug 27, 2016

[c++] default constructor overload in private section.

Is constructible?


i.e
Having a constructor=default in private section,
that constructor still participates in function overload signature matching.

Sep 16, 2015

[C++] Compiler generated member functions

Compiler generated default:
Destructor:
Compiler will generate default destructor that will call data member's destructor.

Move constructor:
compilers typically generate code to destroy this's data member
in the event that an exception arises inside the move constructor.

Move assignment:
The compiler-generated move assignment operator needs to
destroy this object's data member before
it being reassigned from rhs's data.

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