-1

For example, I have a class definition:

#include <string>
using std::string;

class human
{
public:
    human(string, string);
private:
    string firstName, secondName;
};

Is there a difference in these ways of describing the constructor?

human::human(string fname, string sname)
{
    firstName = fname;
    secondName = sname;
}

human::human(string fname, string sname)
:firstName(fname), secondName(sname){}
Orange Fox
  • 147
  • 7

3 Answers3

2

Yes, there is the diference. Imagine you have a non-trivially-constructible class

class NTCClass {
    int i;
public:
    NTCClass(int i) : i(i) {}
};

then you have to use the second form of initialization if this class is memeber of another:

class Wrapper {
    NTCClass c;
public:
    Wrapper() : c(0) {} // correct
    Wrapper() { c = NTCClass(0); } // illegal, c is not trivially constructible
};

the c = NTCClass(0); is actually assignment to the already constructed object, so the default constructor has already been called here. (If the class doesn't have default constructor, this will fail with compile error).

Erbureth
  • 3,378
  • 22
  • 39
1

Yes, there is a difference. In the first example firstName and secondName are instantiated before you enter the constructor body. Once they have been instantiated an assignment is performed on firstName then secondName. In the second example firstName and secondName are instantiated through their copy constructor without the additional assignment.

Captain Obvlious
  • 19,754
  • 5
  • 44
  • 74
1
  • Yes there's big difference.

  • In the first version the member variables firstName and secondName will be first constructed (i.e., the default constructor of std::string is going to be evoked for each one of them), and then their assignment operator is going to be evoked in the constructor's body of class human in order for them to take the value of fname and sname respectively.

  • In the second version member variables firstName and secondName are initialized upon the time of their creation (i.e., only their constructors are going to be evoked). Thus, you avoid the redundant calls of the assignment operator in the constructor's body.

  • That is, the second version is more efficient and should be preferred when ever possible.

  • One thing also to mention is that you should pass the input arguments fname and sname by constant reference and not by value in order to avoid the invocation of the copy constructor for each one of them.


Thus, this is the version you should prefer:

human::human(std::string const &fname, std::string const &sname)
: firstName(fname), secondName(sname){}
101010
  • 41,839
  • 11
  • 94
  • 168