Initializing class object as member

S

subramanian

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 ?
 
O

Ondra Holub

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::eek:perator=(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;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,526
Members
44,997
Latest member
mileyka

Latest Threads

Top