subramanian napsal:
Consider the following program:
#include <iostream>
#include <string>
class Test {
public:
Test(const std::string &val);
private:
std::string str;
};
Test::Test(const std::string &val) : str(val)
{
// str = val;
std::cout << "from one arg ctor of Test class: " << str << '\n';
return;
}
int main(void)
{
Test tmp("tmp object");
return 0;
}
This program's output is
from one arg ctor of Test class: tmp object
which is expected. In the ctor, Test::Test(const std::string &val) :
str(val),
instead of using str(val), if I uncomment str = val, then also the same
output is printed. Among these two ways of initializing str, which is
preferable and why ?
Preffered form is
Constructor()
: member(prm1, prm2, ...)
{
}
because it simply calls constructor of member.
In form
Constructor()
{
member = ...;
}
Is called default constructor (without parameters) first and then
assignment operator. For built-in types it may be optimized, but for
class instances it works described way - it may not be optimized,
because there is no guarantee, that result of sequence {default
constructor, assignment operator} is the same as result of non-default
constructor (although in well designed code it should be so).
You can see this behaviour on following sample program:
#include <iostream>
class TestClass
{
public:
TestClass()
{
std::cout << "TestClass()\n";
}
TestClass(int data)
: data_(data)
{
std::cout << "TestClass(int)\n";
}
TestClass(const TestClass& tc)
: data_(tc.data_)
{
std::cout << "TestClass(const TestClass&)\n";
}
TestClass& operator=(int data)
{
std::cout << "TestClass::operator=(int)\n";
data_ = data;
return *this;
}
private:
int data_;
};
class Test1
{
public:
Test1()
: tc_(10)
{
}
private:
TestClass tc_;
};
class Test2
{
public:
Test2()
{
tc_ = 10;
}
private:
TestClass tc_;
};
int main()
{
Test1 t1;
std::cout << "---------------\n";
Test2 t2;
}