By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,672 Members | 1,628 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,672 IT Pros & Developers. It's quick & easy.

constructor problem

P: n/a
Here are my codes:

#include <iostream>

using namespace std;

class Test
{
public:
Test() { cout << "Test()" << endl; }
Test(const string& s) { str = s; cout<< "Test(string)" << endl; }
Test(const Test& t) { str = s; cout << "Test(const Test&)" << endl;
}
private:
string str;
}

int main()
{
string str("hello");
Test t1(str);
Test t2 = str;
return 0;
}

I use VC++ 7.0 to compile and run the program, the result is:
-----------------
Test(string)
Test(string)
-----------------

copy constructor has not been called.
But in "C++ Primer 4th Edition", Ch 13.1
-----------------------------------------------------------
Usually the difference between direct- or copy-initialization is at
most a matter of low-level optimization. However, for types that do not
support copying, or when using a constructor that is nonexplicit
(Section 12.4.4, p. 462) the distinction can be essential:

ifstream file1("filename"); // ok: direct initialization
ifstream file2 = "filename"; // error: copy constructor is private
// This initialization is okay only if
// the Sales_item(const string&) constructor is not explicit
Sales_item item = string("9-999-99999-9");
-----------------------------------------------------------

However, even if I declare the copy constructor of Test class as
private, still it can be compiled and executed correctly. That seems
the following sentences are treated as the same:
--------------------
Test t1(str);
Test t2 = str;
--------------------

Hope sb can help me.
Thanks in advance!

Dec 29 '06 #1
Share this Question
Share on Google+
9 Replies


P: n/a

campos wrote:
Here are my codes:

#include <iostream>
#include <ostream>
#include <string>
>
using namespace std;

class Test
{
public:
Test() { cout << "Test()" << endl; }
always, always initialize all your members.

Test() : str() { std::cout << "default Test()" << std::endl; }
Test(const string& s) { str = s; cout<< "Test(string)" << endl; }
The above should be:
Test(const std::string& s) : str(s) { std::cout<<
"Test(string)" << std::endl; }
Which by the way, is a conversion ctor.
Test(const Test& t) { str = s; cout << "Test(const Test&)" << endl;
}
private:
string str;
}
; // semicolon required
>
int main()
{
string str("hello");
Test t1(str);
Test t2 = str; // invoking conversion ctor
return 0;
}

I use VC++ 7.0 to compile and run the program, the result is:
-----------------
Test(string)
Test(string)
-----------------

copy constructor has not been called.
There was no copy.
>

But in "C++ Primer 4th Edition", Ch 13.1
-----------------------------------------------------------
Usually the difference between direct- or copy-initialization is at
most a matter of low-level optimization. However, for types that do not
support copying, or when using a constructor that is nonexplicit
(Section 12.4.4, p. 462) the distinction can be essential:

ifstream file1("filename"); // ok: direct initialization
ifstream file2 = "filename"; // error: copy constructor is private
// This initialization is okay only if
// the Sales_item(const string&) constructor is not explicit
Sales_item item = string("9-999-99999-9");
-----------------------------------------------------------

However, even if I declare the copy constructor of Test class as
private, still it can be compiled and executed correctly. That seems
the following sentences are treated as the same:
--------------------
Test t1(str);
Test t2 = str;
--------------------
Try:
Test t2 = t1; // thats a copy since t1 and t2 are of the same type
t1 = t2; // thats now an assignment

Dec 29 '06 #2

P: n/a
Salt_Peter wrote:
campos wrote:
class Test
{
public:
Test() { cout << "Test()" << endl; }

always, always initialize all your members.

Test() : str() { std::cout << "default Test()" << std::endl; }
Why? You're just default constructing the std::string, anyway.

Dec 29 '06 #3

P: n/a
"campos" <hu******@gmail.comwrote in message
news:11**********************@k21g2000cwa.googlegr oups.com
Here are my codes:

#include <iostream>

using namespace std;

class Test
{
public:
Test() { cout << "Test()" << endl; }
Test(const string& s) { str = s; cout<< "Test(string)" << endl; }
Test(const Test& t) { str = s; cout << "Test(const Test&)" << endl;
}
private:
string str;
}

int main()
{
string str("hello");
Test t1(str);
Test t2 = str;
return 0;
}

I use VC++ 7.0 to compile and run the program, the result is:
-----------------
Test(string)
Test(string)
-----------------

copy constructor has not been called.
This is permissible as an optimization. However, according to the Standard,
the copy constructor is required to be accessible even if not used in this
scenario. Comeau online refuses to compile the code when the copy
constructor is private. VC++ 2005 also refuses to compile it if language
extensions is disabled (/Za switch).
--
John Carson
Dec 29 '06 #4

P: n/a
Ctors are implicit by default..which means this statement
Test t2 = str; is no different from Test t2 (str);

Make the 2nd ctor as explicit
explicit Test(const string& s))
if you want to avoid an assignment to call a non copy ctor.

-
Venkatesh
John Carson wrote:
"campos" <hu******@gmail.comwrote in message
news:11**********************@k21g2000cwa.googlegr oups.com
Here are my codes:

#include <iostream>

using namespace std;

class Test
{
public:
Test() { cout << "Test()" << endl; }
Test(const string& s) { str = s; cout<< "Test(string)" << endl; }
Test(const Test& t) { str = s; cout << "Test(const Test&)" << endl;
}
private:
string str;
}

int main()
{
string str("hello");
Test t1(str);
Test t2 = str;
return 0;
}

I use VC++ 7.0 to compile and run the program, the result is:
-----------------
Test(string)
Test(string)
-----------------

copy constructor has not been called.

This is permissible as an optimization. However, according to the Standard,
the copy constructor is required to be accessible even if not used in this
scenario. Comeau online refuses to compile the code when the copy
constructor is private. VC++ 2005 also refuses to compile it if language
extensions is disabled (/Za switch).
--
John Carson
Dec 29 '06 #5

P: n/a
"Venkatesh" <lb*********@gmail.comwrote in message
news:11**********************@k21g2000cwa.googlegr oups.com
Ctors are implicit by default..which means this statement
Test t2 = str; is no different from Test t2 (str);
Incorrect. Implicit constructors means that

Test t2 = str;

is no different from

Test t2 = Test(str);

Subject to the qualification below, both of these involve a constructor call
to create a Test temporary from str, and a copy constructor to copy this
Test temporary to t2. Both are different from

Test t2(str);

which does not involve a copy constructor. See section 12.6 of the Standard.

By section 12.8/15 of the standard, it is possible with both

Test t2 = str;

and

Test t2 = Test(str);

to omit the copy constructor call as an optimization.
Make the 2nd ctor as explicit
explicit Test(const string& s))
if you want to avoid an assignment to call a non copy ctor.
That will mean that

Test t2 = str;

doesn't compile. However

Test t2 = Test(str);

will compile and copy construction may be omitted as an optimization.

--
John Carson
Dec 29 '06 #6

P: n/a
John Carson wrote:
"Venkatesh" <lb*********@gmail.comwrote in message
news:11**********************@k21g2000cwa.googlegr oups.com
Ctors are implicit by default..which means this statement
Test t2 = str; is no different from Test t2 (str);

Incorrect. Implicit constructors means that

Test t2 = str;

is no different from

Test t2 = Test(str);

Subject to the qualification below, both of these involve a constructor call
to create a Test temporary from str, and a copy constructor to copy this
Test temporary to t2. Both are different from

Test t2(str);

which does not involve a copy constructor. See section 12.6 of the Standard.

By section 12.8/15 of the standard, it is possible with both

Test t2 = str;

and

Test t2 = Test(str);

to omit the copy constructor call as an optimization.
May be, i should have elaborated a bit more.
AFAIK, if something happens to go through an implicit ctor, then copy
ctor will not be called which means
Test t2 = str; is no different from Test t2 (str);
where as Test t2 = Test(str) may skip or go through the copy ctor.

Also a closer look at the creation of these two objects will tell the
fact that calls made for 'Test t2 = str' are exaclty the same as 'Test
t2(str)'

Please refer Bjarne's TCPL section 11.3.4 where reads like complex x=2
is equivalent to complex x(2) and also that complex y = complex(2,0) is
equivalent to complex y(2, 0);
Make the 2nd ctor as explicit
explicit Test(const string& s))
if you want to avoid an assignment to call a non copy ctor.

That will mean that

Test t2 = str;

doesn't compile. However

Test t2 = Test(str);

will compile and copy construction may be omitted as an optimization.

--
John Carson
I can't help in this regard as the call to the ctor Test(const string&
s) is made explicit which is not required here.

-
Venkatesh

Dec 29 '06 #7

P: n/a
"Venkatesh" <lb*********@gmail.comwrote in message
news:11**********************@k21g2000cwa.googlegr oups.com
John Carson wrote:
>"Venkatesh" <lb*********@gmail.comwrote in message
news:11**********************@k21g2000cwa.googleg roups.com
>>Ctors are implicit by default..which means this statement
Test t2 = str; is no different from Test t2 (str);

Incorrect. Implicit constructors means that

Test t2 = str;

is no different from

Test t2 = Test(str);

Subject to the qualification below, both of these involve a
constructor call to create a Test temporary from str, and a copy
constructor to copy this Test temporary to t2. Both are different
from

Test t2(str);

which does not involve a copy constructor. See section 12.6 of the
Standard.

By section 12.8/15 of the standard, it is possible with both

Test t2 = str;

and

Test t2 = Test(str);

to omit the copy constructor call as an optimization.

May be, i should have elaborated a bit more.
AFAIK, if something happens to go through an implicit ctor, then copy
ctor will not be called which means
Test t2 = str; is no different from Test t2 (str);
where as Test t2 = Test(str) may skip or go through the copy ctor.
This is just plain wrong. As I have already stated,

Test t2 = str;
and
Test t2 = Test(str);

are the same when there is an implicit constructor. In either case the copy
constructor may or may not be called. In *both* cases, the copy constructor
is required to be accessible even if not called.

With

Test t2 (str);

by contrast, the copy constructor is *never* called and is not required to
be accessible.
Also a closer look at the creation of these two objects will tell the
fact that calls made for 'Test t2 = str' are exaclty the same as 'Test
t2(str)'
Wrong. Compile them using Comeau online with a private copy constructor.

http://www.comeaucomputing.com/tryitout/

Observe that

Test t2 (str);

will compile but

Test t2 = str;

will *not* compile.
Please refer Bjarne's TCPL section 11.3.4 where reads like complex x=2
is equivalent to complex x(2) and also that complex y = complex(2,0)
is equivalent to complex y(2, 0);
You are misreading this. Start in the previous section (p. 270), where he
says that

complex b = 3;

means

complex b = complex(3);

Then in section 11.3.4, he says that:

"In principle, copy constructors are used in simple initializations such as:

complex x = 2;
complex y = complex(2,0);"

Such initializations are therefore NOT equivalent to

complex y(2,0);

because it is NOT the case that "in principle, copy constructors are used"
in such initializations.

He also comments that: "It is possible to restrict the set of values
accepted by the = style of initialization compared to the () style by making
the copy constructor private", i.e., inaccessible, which is the point I have
made above.

--
John Carson
Dec 29 '06 #8

P: n/a
enrich you knowledge by using other source
http://www.fredosaurus.com/notes-cpp...structors.html
http://en.wikipedia.org/wiki/Copy_constructor

br (best regards)

"campos" <hu******@gmail.comwrote in message
news:11**********************@k21g2000cwa.googlegr oups.com...
Here are my codes:

#include <iostream>

using namespace std;

class Test
{
public:
Test() { cout << "Test()" << endl; }
Test(const string& s) { str = s; cout<< "Test(string)" << endl; }
Test(const Test& t) { str = s; cout << "Test(const Test&)" << endl;
}
private:
string str;
}

int main()
{
string str("hello");
Test t1(str);
Test t2 = str;
return 0;
}

I use VC++ 7.0 to compile and run the program, the result is:
-----------------
Test(string)
Test(string)
-----------------

copy constructor has not been called.
But in "C++ Primer 4th Edition", Ch 13.1
-----------------------------------------------------------
Usually the difference between direct- or copy-initialization is at
most a matter of low-level optimization. However, for types that do not
support copying, or when using a constructor that is nonexplicit
(Section 12.4.4, p. 462) the distinction can be essential:

ifstream file1("filename"); // ok: direct initialization
ifstream file2 = "filename"; // error: copy constructor is private
// This initialization is okay only if
// the Sales_item(const string&) constructor is not explicit
Sales_item item = string("9-999-99999-9");
-----------------------------------------------------------

However, even if I declare the copy constructor of Test class as
private, still it can be compiled and executed correctly. That seems
the following sentences are treated as the same:
--------------------
Test t1(str);
Test t2 = str;
--------------------

Hope sb can help me.
Thanks in advance!

Dec 29 '06 #9

P: n/a
Got it !

Thanks John~

"John Carson д
"
"campos" <hu******@gmail.comwrote in message
news:11**********************@k21g2000cwa.googlegr oups.com
Here are my codes:

#include <iostream>

using namespace std;

class Test
{
public:
Test() { cout << "Test()" << endl; }
Test(const string& s) { str = s; cout<< "Test(string)" << endl; }
Test(const Test& t) { str = s; cout << "Test(const Test&)" << endl;
}
private:
string str;
}

int main()
{
string str("hello");
Test t1(str);
Test t2 = str;
return 0;
}

I use VC++ 7.0 to compile and run the program, the result is:
-----------------
Test(string)
Test(string)
-----------------

copy constructor has not been called.

This is permissible as an optimization. However, according to the Standard,
the copy constructor is required to be accessible even if not used in this
scenario. Comeau online refuses to compile the code when the copy
constructor is private. VC++ 2005 also refuses to compile it if language
extensions is disabled (/Za switch).
--
John Carson
Dec 30 '06 #10

This discussion thread is closed

Replies have been disabled for this discussion.