473,385 Members | 1,748 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

When copy constructors become handy?

Dear all,

So passing and returning a class object is the time when to include the
definition of the copy constructor into the class definition. But if we
don't call by value or return by value, we do not need to use the
copy-constructor. So depending on the above reasoning I can avoid call
by value and return by value for class objects, this bypasses the
problem or it seems to me like that.

Could any one give me some simple examples when copy constructors are
indispensible tools in C++ class implementations?

Thx

Apr 23 '06 #1
10 2510
utab wrote:
Dear all,

So passing and returning a class object is the time when to include the
definition of the copy constructor into the class definition.
Not necessarily. There is a default copy ctor provided automatically.
You only need to write your own if the default is not satisfactory.
But if we
don't call by value or return by value, we do not need to use the
copy-constructor. So depending on the above reasoning I can avoid call
by value and return by value for class objects, this bypasses the
problem or it seems to me like that.
Function arguments and return values aren't the only situations where
objects are copied. Sometimes you just need to make a copy:

A a1;
A a2 = a1; // copy ctor called

Besides, you may find that never calling or returning by value is
incredibly onerous. What do you have against copy ctors?

Could any one give me some simple examples when copy constructors are
indispensible tools in C++ class implementations?

Thx

Apr 23 '06 #2

utab wrote:
Dear all,

So passing and returning a class object is the time when to include the
definition of the copy constructor into the class definition.
Passing by value and returning by value are two ways of invoking copy
construction for objects of class type. But just because the copy
constructor is used doesn't mean you need to define it yourself. If you
don't define it, the compiler will do it for you. The compiler
generated copy constructor will perform a memberwise copy of all data
members and will copy base class objects using their copy constructors.
Unless that is not sufficient for your needs, you do not need to define
the copy constructor, even if you do copy objects.
But if we
don't call by value or return by value, we do not need to use the
copy-constructor.
Not true.

std::string s1("text");
std::string s2(s1);

s2 is constructed using the copy constructor of the std::string class,
but nothing is passed or returned by value.
So depending on the above reasoning I can avoid call
by value and return by value for class objects, this bypasses the
problem or it seems to me like that.
What problem?
Could any one give me some simple examples when copy constructors are
indispensible tools in C++ class implementations?


You should write a copy constructor for any class where the compiler
generated copy constructor is not sufficient. Generally this means
classes that own resources, e.g. memory referred to by a bald pointer.
Google for the "rule of three" too. If you need to write your own copy
constructor, you probably need to write your own assignment operator
and destructor as well.

Notice that the decision whether to write your own copy constructor or
rely on the compiler generated one has *nothing* to do with whether you
think the code you're about to write will copy objects. Even if you
don't plan to copy any objects immediately, you should still write the
copy constructor (or disable copying - see below) if the compiler
generated copy constructor is not sufficient. Otherwise, one day you or
someone else will come along, write some new code that does copying and
unwittingly introduce bugs because the wrong copy constructor is used.

You have another option too. If you want to disable copying for your
class, declare the copy constructor private. Declare the assignment
operator private too because it certainly makes no sense to disable
copying but allow assignment.

class foo
{
private:
foo(const foo&);
foo& operator=(const foo&);
};

An attempt to copy or assign foo objects will result in a compile
error. Declaring your own copy constructor (even though it is private
and you have not provided a definition) suppresses the compiler
generated one.

Gavin Deane

Apr 23 '06 #3

A a1;
A a2 = a1; // copy ctor called

for this the default copy constructor does the trick or ??

Apr 23 '06 #4

utab wrote:
A a1;
A a2 = a1; // copy ctor called

for this the default copy constructor does the trick or ??


What do you mean by "default copy constructor"? There are default
constructors and there are copy constructors. They are two different
things.

As I said in my other post in this thread (I appreciate you may not
have seen that yet), *if* you do not declare a copy constructor, the
compiler *will* generate one for you. A class can either have the
compiler generated copy constructor or a copy constructor you write. It
cannot have both.

Whether it is appropriate to rely on the compiler generated copy
constructor has *nothing* to do with the way in which copying is
invoked (e.g. creating a variable like the code above vs. passing an
object to a function by value), but has everything to do with the
internal nature of the object.

Gavin Deane

Apr 23 '06 #5
if I do not supply mine for the class, for simple copy operations is
this enough(I think not because the calling and destruction of the
objects do not match then but I am nor sure s I will check that...)
A a1;
A a2 = a1; // copy ctor called


Thx.

Apr 24 '06 #6

utab wrote:
if I do not supply mine for the class, for simple copy operations is
this enough(I think not because the calling and destruction of the
objects do not match then but I am nor sure s I will check that...)


They will match - one constructor will be called for every destructor
called.
Of course, there can be different constructors (default/copy/...) so if
you want
to count the number of objects constructed you'll have to count every
constructor call (including the compiler-generated!)

In general, the rule-of-three applies: you need to write a copy
constructor,
assignment, and a destructor if you need any of those.

HTH,
Michiel Salters

Apr 24 '06 #7
I tried something simple to better understand the construction
involving copy constructors and the rule of three, but I have several
questions;

#include <iostream>

using std::cout;
using std::endl;

class X{
public:
X(int a){x=a;++count;cout<< "ctor" << std::endl;cout<< count <<
std::endl;}
X(const X&){++count;cout<< "cctor" << std::endl;cout<< count <<
std::endl;}
// X& operator=(X& rhs){x=rhs.x;return *this;}
int getx(){return x;}
~X(){--count;cout<< "dtor" << std::endl; cout<< count <<
std::endl;}
private:
int x;
static int count;

};
int X::count = 0;
int main(){
X a(5),b(10);
//X c(a);
b=a;
cout << b.getx() << std::endl;
return 0;
}

If I comment the overloaded = operator, I can not see the output for my
copy constructor. I get

ctor
1
ctor
2
5
dtor
1
dtor
0

When I initialize an object with another one cctor works and
ctor
1
ctor
2
cctor
3
5
dtor
2
dtor
1
dtor
0

When the object with object initialization is commented and = operator
is used but the copy constructor is not used so , while using the rule
of three, whichever is appropriate will be used is that true. Since I
am using =, this one is used. I am a bit confused.. :-((

Apr 24 '06 #8

utab wrote:
I tried something simple to better understand the construction
involving copy constructors and the rule of three, but I have several
questions;

#include <iostream>

using std::cout;
using std::endl;

class X{
public:
X(int a){x=a;++count;cout<< "ctor" << std::endl;cout<< count <<
std::endl;}
X(const X&){++count;cout<< "cctor" << std::endl;cout<< count <<
std::endl;}
// X& operator=(X& rhs){x=rhs.x;return *this;}
int getx(){return x;}
~X(){--count;cout<< "dtor" << std::endl; cout<< count <<
std::endl;}
private:
int x;
static int count;

};
int X::count = 0;
int main(){
X a(5),b(10);
//X c(a);
b=a;
cout << b.getx() << std::endl;
return 0;
}

If I comment the overloaded = operator, I can not see the output for my
copy constructor.
I don't know what you mean. There are two lines commented out in your
code above. One is the definition of the assignment operator in the
class. The other is X c(a); which copy constructs a new object c from
the object a. Copy construction is a completely different thing from
assignment so commenting out the assignment operator is irrelevant to
what happens when you try and copy construct an object. The line X
c(a); is the only occurrance of copy construction in your code so if
you comment out that line it is not surprising that you don't see your
copy constructor called. b=a; is assignment - it has nothing to do with
copy construction.

Your assignment operator is identical in effect to the one the compiler
would have generated if you hadn't done it yourself, so whether yours
is commented out or not has no effect on the behaviour of your code.
I get

ctor
1 This is the construction of object a using the value 5
ctor
2 This is the construction of object b using the value 10
5 This is the result of b.getx() after the assignment b=a; changes the
value of x within b to 5.
dtor
1 This is the destruction of object b
dtor
0 This is the destruction of object a

When I initialize an object with another one cctor works and
I assume what you mean here is that you've uncommented the line X c(a);
to see what difference it makes.
ctor
1 This is the construction of object a using the value 5
ctor
2 This is the construction of object b using the value 10
cctor
3 This is the copy construction of object c from object a
5 This is the result of b.getx() after the assignment b=a; changes the
value of x within b to 5.
dtor
2 This is the destruction of object c
dtor
1 This is the destruction of object b
dtor
0 This is the destruction of object a
When the object with object initialization is commented and = operator
is used but the copy constructor is not used so , while using the rule
of three, whichever is appropriate will be used is that true. Since I
am using =, this one is used. I am a bit confused.. :-((


Construction (whether it be copy construction or any other form of
construction) is a completely different thing from assignment. The copy
constructor is used when *a new object* is being constructed as a copy
of an existing object. The assignment operator is used when *an object
that already exists* has a new value assigned to it.

Gavin Deane

Apr 24 '06 #9
utab wrote:
Dear all,

So passing and returning a class object is the time when to include the
definition of the copy constructor into the class definition. But if we
don't call by value or return by value, we do not need to use the
copy-constructor. So depending on the above reasoning I can avoid call
by value and return by value for class objects, this bypasses the
problem or it seems to me like that.

Could any one give me some simple examples when copy constructors are
indispensible tools in C++ class implementations?

Thx


In addition to all other posts, may I remind you without a copy
constructor the standard containers can be quite embarrassing to use:

#include <vector>
#include <list>

class C
{
private:
C(const C&);
public:
C(){}
~C(){}
};

int main()
{
std::vector<C> v; // ERROR
std::list<C> l; // ERROR
std::deque<C> d; // ERROR
}

Regards,
Ben
Apr 24 '06 #10
See now, Thank you for the detailed explanations. I appreciate that.

Regards,

Apr 24 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

42
by: Edward Diener | last post by:
Coming from the C++ world I can not understand the reason why copy constructors are not used in the .NET framework. A copy constructor creates an object from a copy of another object of the same...
2
by: Birt | last post by:
My understanding about defining your own copy and assignment constructors is whenever there is a member of pointer type. Is this true or is there any exception to this"rule"? How about when you...
8
by: Jesper | last post by:
Hi, Does the concept "copy constructor" from c++ excist in c#. What is the syntax. best regards Jesper.
4
by: Robert Zurer | last post by:
Hello All, Is it considered a best practice to always write a parameterless constructor for any object - just in case? I'm not sure. I want my object to have all it absolutely requires to...
13
by: MurphyII | last post by:
Just a little sample : class A { public: A( ) { } template<typename T> A( const typename T& a) {
26
by: saxenavaibhav17 | last post by:
what is Deep Copy, Shallow copy and Bitwise copy, Memberwise copy? and what is the difference between them? pls help vaibhav
6
by: Richard Thompson | last post by:
Hi - I have a program which was previously working (but wasn't well tested). I've added a new function call, and it now doesn't compile. The call requires a copy constructor, but the compiler...
9
by: Anthony Williams | last post by:
Hi, Should the following compile, and what should it print? #include <memory> #include <iostream> void foo(std::auto_ptr<intx) { std::cout<<"copy"<<std::endl;
34
by: =?ISO-8859-1?Q?Marcel_M=FCller?= | last post by:
Hi, is there a way to avoid the automatic copy constructor generation. I do not want the object to be non-copyable. I simply do not want that copying is done by the default copy constructor. But...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.