Hi all,

Is it possible to call constructor and destructor explicitally?

Recommended Answers

All 8 Replies

Hi harris, yes we can call constructor explicitly, but we cant call destructor.]

class sample
{
   public:
      explicit sample() { cout << "Constructor called" << endl; }
      ~sample() {}
};
int main()
{
    sample obj(); //explict call only here allow because of explicit keywoed
}

I'll get the bug out the way first:

>sample obj(); //explict call only here allow because of explicit keywoed
This isn't a constructor call, it's a function declaration. Remove the parens and you'll construct a new object called obj. While it's still calling the constructor, one could argue that a direct constructor call might look more like this:

sample obj = sample();

At least conceptually, a temporary is created using a standalone constructor call, then obj is copy constructed from that temporary. In practice, this line will most likely be optimized such that the temporary goes away and is functionally equivalent to sample obj; .

>Is it possible to call constructor and destructor explicitally?
Yes, in both cases. Any time you create an object you're calling a constructor explicitly. Explicit destructor calls are less common because they're rarely needed. One such example is when using placement new to allocate memory:

#include <iostream>
#include <ostream>

class test {
    int x;
public:
    explicit test(int x): x(x) { std::cout<<"Constructor called\n"; }
    ~test() { std::cout<<"Destructor called\n"; }
public:
    friend std::ostream& operator<<(std::ostream& out, const test& rhs)
    {
        return out<< rhs.x;
    }
};

int main()
{
    char base[sizeof(test)];
    test *p = new(base) test(12345);

    std::cout<< *p <<'\n';
    p->~test();
}

Hi harris, yes we can call constructor explicitly, but we cant call destructor.]

class sample
{
   public:
      explicit sample() { cout << "Constructor called" << endl; }
      ~sample() {}
};
int main()
{
    sample obj(); //explict call only here allow because of explicit keywoed
}

That doesn't work, because you can only use the explicit keyword with a constructor that takes one (1) argument to prevent use of the assignment operator in an object declaration. Did you take the time to compile this? Unless your compiler works different than mine, you'll get a warning about a function declaration and never get into the constructor.

@OP:
You can call the constructor(s) explicitly ... kind of... They are only callable when an object is being created, you can not call them any other time. Just like for function overloading, which constructor actually gets called is dependent on how you declare your object.

Conversely, you can not call destructors explicitly, except through Dynamic Memory Management. They are automatically called when an object's life ends (either the object is deleted (freeing dynamic memory) or it goes out of scope).

Version 1 (without Dynamic Memory):

class sample
{
  public:
    sample(): m_prvInt(0) {cout << "Default constructor called" << endl;}
    explicit sample(int value):m_prvInt(value) { cout << "Explicit Constructor called" << endl; }
    ~sample() {}
  private:
    int m_prvInt;
};

int main()
{
    sample obj1;  //call to default constructor
    //sample objBad = 5; //compile error, not allowed because of explicit keyword
    sample objGood(10); //required format because of explicit keyword

    return 0;  //end of scope, all destructors called automatically
}

Version 2 (with Dynamic Memory):

class sample
{
  public:
    sample(): m_prvInt(0) {cout << "Default constructor called" << endl;}
    explicit sample(int value):m_prvInt(value) { cout << "Explicit Constructor called" << endl; }
    ~sample() {}
  private:
    int m_prvInt;
};

int main()
{
    sample *obj1 = new sample;  //"explicit" call to default constructor
    sample *objGood = new sample(10);  //"explicit" call to overloaded constructor

    delete obj1;    //"explicit" call to destructor
    delete objGood; //"explicit" call to destructor

    return 0;
}

EDIT:
Oops, Narue beat me to it.

If I may add a few things to the already good answers from Narue and Fbody.

First, although Narue showed a case where explicitly calling a destructor, it's important to say that there is virtually no other reason where an explicit call to the destructor makes sense and the placement new are very rarely used and not recommended in general. Because most of the time, objects will be created either dynamically (with new or new[]) or as a scoped object (local variable), and in both of these cases, calling the destructor explicitly is VERY error-prone (basically any non-trivial destructor will cause a crash when it is implicitly called again).

Second, it is important to know the behavior of the following code, because many beginner programmers might be tempted to do that (in a less trivial case):

class Foo {
    int a;
    double b;
  public:
    Foo(int A, double B) : a(A), b(B) { }; //Parametrized constructor.
    Foo() //default constructor
    {
      //might be tempted to do this (in a less trivial class of course).
      Foo(0,0.0); //calling the other constructor explicitly. BIG MISTAKE!
    };
    //In this trivial case, the following constructor would make more sense:
    Foo(int A = 0, double B = 0.0) : a(A), b(B) { };
};

One might expect that the above calls the parametrized constructor on the "this" pointer that is relevant to the default constructor, i.e. that this will actually initialize the values of a and b to default values 0 and 0.0. But in fact, this will create a temporary object of class Foo with default parameters that will be deleted right after the semi-colon. In reality, of course, the compiler will warn you that this line has no effect, then will warn that a and b might be used with uninitialized values, and finally will optimize away that constructor call because it creates a useless temporary.

@Narue
Because of perverse curiosity, I must know. When and why have you used placement new before? Perhaps a hardware interface?

>When and why have you used placement new before?
I've personally used it to implement the std::allocator class in the allocate and construct member functions:

pointer allocate(size_type n)
{
    if (mem_block_overflow(n))
        throw std::bad_alloc();

    return ::operator new(N * sizeof(T));
}

void construct(pointer p, const T& val)
{
    ::new (p) T(val);
}

Beyond that I generally stick to the allocator class because it does the same thing in a more convenient package. Though I suspect it would be handy for writing things like memory pools on memory restricted systems where the allocator class would be too heavy.

These use cases are common when programming under Symbian. Actually, I don`t think i`ve ever needed to call destructor other than on Symbian system, if my memory serves me right.

>>Conversely, you can not call destructors explicitly, except through Dynamic Memory Management

Actually you can :

#include <iostream>
using namespace std;
struct Foo{
	Foo(){cout<<"Ctor\n";}
	~Foo(){cout<<"Dtor\n";}
};
int main(){       
	Foo f;
	f.~Foo();
  return 0;
}

But you see the problem, the destructor is called 2 times.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.