Adib
Adib

Reputation: 723

how constructor could be called sooner than member variables in a class?

consider following code: I know that when you create an object of class C first member variables will be constructed then order of construction will be abc and deconstruction CBA . now question is that if there is a way to call constructor of class C sooner than member variables ? to have order of cab and for deconstruction BAC

how i could change order that way first constructor of class be called then member variables.

#include <iostream>
#include <exception>

class A {
public:
  A() {
    std::cout << 'a';

  }
  ~A() { std::cout << 'A'; }
};


class B {
public:
  B() { std::cout << 'b'; }
  ~B() { std::cout << 'B'; }

};

class C {
public:
  C() {
    std::cout << 'c';

  }
  ~C() { std::cout << 'C'; }

    A m_a ;
    B m_b;
        };


void foo() {  C c; }

int main() {
  try {
    foo();
  }
  catch (std::exception &) {
    std::cout << "catch";

  }
}

Upvotes: 2

Views: 64

Answers (2)

More of a workaround than actually breaking construction order (which isn't possible). Store the members by smart pointer.

class C {
public:
  C() {
    std::cout << 'c';
    m_a = std::make_unique<A>();
    m_b = std::make_unique<B>();
  }
  ~C() { 
     m_b.reset();
     m_a.reset();
     std::cout << 'C';
   }

    std::unique_ptr<A> m_a;
    std::unique_ptr<B> m_b;
};

The instances of the actual objects you care about can now be created at the end of C's constructor. Of course, you pay for it by doing dynamic memory allocation.

Another solution can be to use aligned storage and placement new construction:

class C {
public:
  C() {
    std::cout << 'c';
    new(&m_a) A;
    new(&m_B) B;
  }
  ~C() { 
     m_b.~B();
     m_a.~A();
     std::cout << 'C';
   }

    std::aligned_storage<sizeof(A), alignof(A)>::type m_a;
    std::aligned_storage<sizeof(B), alignof(B)>::type m_b;
};

But either way you have to be very careful and follow to rule of three/five.

Upvotes: 2

Lukasz
Lukasz

Reputation: 348

Or simply:

class C {
public:
    A *m_a;
    B *m_b;

      C() {
        std::cout << 'c';
        m_a = new A;
        m_b = new B;
      }
    ~C() {
        delete m_b;
        delete m_a;
        std::cout << 'C'; }
        };

Use smart pointers to ensure exception safeness

Upvotes: 1

Related Questions