Dissecting Code

Wednesday, February 17, 2010

Explicit, implicit constructors, the = operator and the member initialization list

Consider this piece of code:

#include <iostream>

class B
{
int m_a;
public:
B(){}
B(int a){m_a=a;}
B& operator=(const B &b1){m_a=b1.m_a; return *this;}
int Print()
{
std::cout<<"Hi there";
}
};

class A
{
B m_var;
public:
explicit A(int a)
{
m_var=a;
}
};

int main()
{
A a(3);
return 0;
}



This gives quite an insight into the working of constructors, and the usage of the assignment operator. I’ll step through the code:


  • As expected, the constructor for A is invoked.

  • As the control enters A’s constructor, constructor for B is called, that initializes m_var with a junk value.

  • Constructor for B is called to create an object from int a (as B’s constructor is not explicit, this is allowed by the compiler).

  • B’s = operator is invoked to assign the value of the created temp object to m_var.


Clearly seen is that it would have been better to use the member initialization list to assign B with something like:


#include <iostream>

class B
{
int m_a;
public:
B(){}
B(int a){m_a=a;}
B& operator=(const B &b1){m_a=b1.m_a; return *this;}
int Print()
{
std::cout<<"Hi there";
}
};

class A
{
B m_var;
public:
explicit A(int a): m_var(a)
{
}
};

int main()
{
A a(3);
return 0;
}


In this case:

  • A’s constructor is invoked.

  • B’s constructor is invoked that sets m_var.m_a to a.


Thus member initialization lists are there for a reason. Use them!

Labels: , , , ,