Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C++ (http://www.go4expert.com/articles/cpp-tutorials/)
-   -   Explicit Constructor in C++ (http://www.go4expert.com/articles/explicit-constructor-cpp-t20756/)

Mridula 25Jan2010 16:10

Explicit Constructor in C++
 

Introduction



This article talks about keyword explicit in C++.

Background



Constructors are functions with the same name as the class. They are used to create the instance of a class. They are provided default by the compiler. But still user can have his/her own constructor declared. We can have a constrctor with a single parameter and use this kind of constructor for doing type conversion or implicit conversion.

For Example:

The code



Code: Cpp

#include<iostream.h>

class A
{
  int data;

public:
  A(int a):data(a)
  {
      cout<<"A::Construcor...\n";
      cout<<"value of data :="<<data<<endl;
  };
};


int main()
{
  A a1 = 37;

  return (0);
}

./a.out
A::Construcor...
value of data :=37


A declaration like below in this example is called as Impliicit Conversion and calls A(int a) constructor to create an A object from the integer value:

A a1 = 37;

If you define the single parameter as an object of another class, then that constructor allows the compiler to perform an automatic type conversion, which is also called as Constructor Conversion.

For Example:

The code



Code: Cpp

#include<iostream.h>

class A
{

public:
  A()
  {
      cout<<"A::Construcor...\n";
  };
};

class B
{
   
public:
   
    B(const A& aObj)
    {
      cout<<"B::Construcor...\n";
    };
};

void display(B bObj)
{
    cout<<"function display...\n";     
}


int main()
{
  A a;
 
  //Call display with A object i.e. a1
  display(a);

  return (0);
}

./a.out
A::Construcor...
B::Construcor...
function display...


In this example, when compiler sees display() called with a A object, it looks at the declaration of display() and finds out it needs B object. Then it looks to see, if there is any way to get a B object from A object and it finds B class's single parameter constructor, which it implictly calls. This results in handing over B 's object to function display().

This one way, may prevent us from overloading display() function for 2 different objects here!! But if you look at the efficiency of function display() - it degrades as it implicitly calls B's constructor, before really calling the display() function and this could be a concern here.

Lets see another example.

The code



Code: Cpp

#include<iostream.h>

class A
{
  int data;

public:
  A(int a):data(a)
  {
      cout<<"A::Construcor...\n";
  };

  friend void display(A obj);
};

void display(A obj)
{
    cout<<"Valud of data in obj :="<< obj.data<<endl;
}

int main()
{
  //Call display with A object i.e. a1
  display(5000);

  return (0);
}

output
-----------
./a.out
A::Construcor...
Valud of data in obj :=5000


When you look at this example, it is very confusing!! Though the function display expects an object of class A, but passing an integer value 5000 seems to be working and it gets converetd to A obj and then calls class A(int a) constructor.

To avoid all such confusions that happens with Implicit Conversion and Constructor Conversion, we can use explicit ketword in constructor declaration. This forces the compiler not to do an implicit conversion and throws an error for this kind of code. And thus make sures the constructor is explicitly called with the right syntax. This keyword is used only for the constructors.

Now lets take the first example and make the constructor explicit and try to call as below:

The code



Code: Cpp

#include<iostream.h>

class A
{
  int data;

public:
  explicit A(int a):data(a)
  {
      cout<<"A::Construcor...\n";
      cout<<"value of data :="<<data<<endl;
  };
};


int main()
{
  A a1 = 37;

  return (0);
}

We will get the below Compiler Error:
---------------------------------------
explicit1.cc: In function `int main()':
explicit1.cc:18: error: conversion from `int'
to non-scalar type `A' requested


Same way, we can avoid Constructor Conversion in above example by making B's constructor as explicit as shown below:

explicit B (const A& aObj)

But explicit on a constructor with multiple arguments has no effect, since such constructors cannot take part in implicit conversions. However, explicit will have an effect if a constructor has multiple arguments and all but one of the arguments has a default value.

For Example:

The code



Code: Cpp

#include<iostream.h>

class A
{
  int data1;
  int data2;
  char* name;

public:
  A(int a, int b=10, char* c = "mridula"):data1(a), data2(b), name(c)
  {
      cout<<"A::Construcor...\n";
  };

  friend void display(A obj);
};

void display(A obj)
{
    cout<<"Valud of data1 in obj := "<< obj.data1<<endl;
    cout<<"Valud of data2 in obj := "<< obj.data2<<endl;
    cout<<"Valud of name in obj  := "<< obj.name<<endl;
}

int main()
{
  //Call display with A object i.e. a1
  display(100);

  return (0);
}

Output:
----------
./a.out
A::Construcor...
Valud of data1 in obj := 100
Valud of data2 in obj := 10
Valud of name in obj  := mridula


In this example, though we have multiple argument constructor
A(int a, int b=10, char* c = "mridula") (all defaulted argument but one), but still there seems to be an implicit conversion happening from type int to A's object.

As said above, it is better to use explicit for such constructor declaration too to avoid any such implicit conversions.

Declare the multiple argumented constructor in the above example as below to avoid implicit conversion:

explicit A(int a, int b=10, char* c = "mridula");

Hope this helps !!

shabbir 6Feb2010 09:28

Re: Explicit Constructor in C++
 
Nominate this Article for Article of the month - Jan 2010

shabbir 18Feb2010 10:55

Re: Explicit Constructor in C++
 
If you liked this articles do vote for it for Article of the month - January 2010

housefull 2Mar2010 23:58

Re: Explicit Constructor in C++
 
Nominate this Article for


All times are GMT +5.5. The time now is 22:00.