?
Solved

Copy constructor

Posted on 2003-03-18
12
Medium Priority
?
388 Views
Last Modified: 2010-04-01
Dear all,
Kindly request somebody who could give a clear idea of Copy constructor and when they are used?
Early reply appreciated.Thanks in advance.
0
Comment
Question by:TCSD
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +2
12 Comments
 
LVL 2

Expert Comment

by:DarthNemesis
ID: 8163517
A copy constructor is used by a class when you create a new class object using an existing class object. For instance:

#include <string>
using namespace std;

void main () {
        string s = "12345";
        string t(s); // this uses the copy constructor for the string class
}
0
 
LVL 3

Expert Comment

by:Kashra
ID: 8163536
A copy constructor is (of course) a special kind of constructor for a class. It takes the form of:

class AClass{
public:
// Copy constructor
AClass(const AClass& rhs);
}

The role of the copy constructor is to provide the compiler a means of creating instances of class A from other instances of class A. Copy constructors are called more often than you think:

1. When you explicitly call them to initialize a new instance of a class:
AClass a; // Default constructor
AClass b(a); // Copy constructor
AClass b = a; // ALSO a copy constructor call

2. When you pass your class by value as a parameter for a function:
void f(AClass p);

int main() {
   AClass a;
   f(a);
   return 0;
}

In this case, the compiler will look at the parameter you pass the function, and then make a copy of it using the constructor for the function to use.

3. Again, when you return a class:
This is similar to case 2 above. When you return an instance of your class, the compiler calls the copy constructor. Neither case 2 or 3 apply when passing by -reference- (because you're not making copies there).

As a general rule, if there's a need for a temporary instance of your class to be created, the compiler will probably end up calling the copy constructor to do it.
0
 
LVL 1

Expert Comment

by:TrueIdiot
ID: 8163566
The best way to learn as much about constructers as possible is to look at some examples. As previous posters have stated, a copy constructer is just a special kind of constructer. The best way to look at constructers is to look at a source file. Wherever your compiler is installed, there should be a folder called "include". Open that, and there's all of the #include<somfile.h> files. Just find one that says vector or matrix or string (any random one will problably do, as long as there's a class in it) and look it over. That's how I learned all about classes.

note: sometimes there is a .cpp file that the actual implementation is in, you should read that. The .h file just gives you the prototypes for the member functions. You gotta read the .cpp file
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Expert Comment

by:Kashra
ID: 8163647
Oh, I forgot my punchline. :)

BECAUSE the copy constructor for your class is called WHENEVER you pass by value and not by reference, you should try to avoid passing by value whenever you can.

Say you have the class I semi-wrote above, and you have a function that does something really simple... like returns what you give it.

AClass giveitback(AClass input)
{ return input; }

In this case, you have the copy constructor called both when you send "input" to your function and again when you return "input" back. You can imagine for more complicated classes, this sort of overhead is really undesirable.

You'd do much better (when you can) to do it this way:

AClass& giveitback(AClass& input)
{ return input; }

And never call the copy constructor.
0
 

Author Comment

by:TCSD
ID: 8164263
Thanks  .But how does it act when deleting the object.
AClass a
AClass b= a
But when U delete a , will b also be deleted...
Just for my understanding...
0
 
LVL 2

Expert Comment

by:DarthNemesis
ID: 8164343
No, b will not be deleted. When the copy constructor is called in your declaration for B, it makes a copy of A in a new memory location. Deleting the original object A from memory won't affect the new object B.
0
 
LVL 2

Expert Comment

by:DarthNemesis
ID: 8164350
As Kashra pointed out, passing an object by reference saves memory because it doesn't invoke the copy constructor and thus doesn't use any more memory. It's in _this_ case, when you create a reference or a pointer to an object, that deleting the original object will invalidate the reference or pointer, because they all point to the same memory location.
0
 
LVL 1

Expert Comment

by:keitha1
ID: 8164532
One of the most important reasons for creating your own copy constructor (as opposed to the one automatically created by the compiler) is to perform what is known as a deep copy.

If a class contains pointer members, the default copy constructor just does a member-by-member copy of the data. That means you now have two objects pointing to the same data. This can be bad news if the destructor frees the pointer because now you will have two objects trying to free the same pointer, or one object pointing to bad data.

There are other reasons too. For instance, maybe two objects can't have the same value for a member called 'm_Name'. In your copy constructor, you could append "Copy_Of_" to the name being copied.
0
 

Author Comment

by:TCSD
ID: 8170958

Thanks everybody!
Keitha1,
This was the one I was confused.So could U explain detailed with example.Class having pointer member and same value for a member..
0
 
LVL 1

Accepted Solution

by:
keitha1 earned 80 total points
ID: 8171824
Here's an example class

class CViewport
{
    CRect  m_ViewRect;       // Visible extents of viewport
    CPen*  m_pCurrentPen;    // Current Windows pen to draw with
    CBrush* m_pCurrentBrush; // Current brush to draw with

public:
    // Public constructor
    CViewport (CRect& initialRect) {
        m_ViewRect = initialRect;
        m_pCurrentPen = new CPen (RGB(255,0,0)); // Create red pen
        m_pCurrentBrush = new CBrush (RGB(255,0,0)); // Create red brush (simplified for example)
    }

    // Public destructor
    virtual ~CViewport () {
        // Release resources
        if (m_pCurrentPen) delete m_pCurrentPen;
        if (m_pCurrentBrush) delete m_pCurrentBrush;
    }

    // Other member functions
    ...
};

Now, if you create an instance of this class such as...

CViewport vp1(Rect(0,0,100,100));

you will have a viewport that is initialized to draw with a red pen and red brush.

If you then wanted to make a copy of that viewport such as

CViewport vp2 = vp1;

The default copy constructor essentially does this:
vp2.m_ViewRect = vp1.m_ViewRect;
vp2.m_pCurrentPen = vp1.m_pCurrentPen;
vp2.m_pCurrentBrush = vp1.m_pCurrentBrush;


Everything appears to be well until one over several things happens:

1) If vp1 goes out of scope before vp2, then vp2 is still active but contains pointers that are the same as was in vp1, which was just freed. Therefore it alive with bad pointers. It gets worse: when vp2 goes out of scope, it too tries to free the same pointers that were already freed in vp1.

2) If vp1 doesn't go out of scope but it's pen and brush are changed (through member functions not shown) then vp2's pen and brush most likely will point to bogus data.

3) If vp2 goes out of scope before vp1, it will free the same pen and brush as in vp1, therefore screwing up vp1 which is still active.


The solution to this problem is to roll your own copy constructor for the class as follows

CViewport::CViewport (const CViewport& src)
{
    m_ViewRect = src.m_ViewRect;  // Copy view rect member
    m_pCurrentPen = new CPen (*src.m_pCurrentPen); // Create its own copy of the source pen
    m_pCurrentBrush = new CBrush (*src.m_pCurrentBrush); // Create its own copy of the source brush
}

Now the two viewports are decoupled from each other. Each has its own copy of dynamically create objects and can be manipulated independently.

Hope that helps and I hope it's understandable because It's pretty late right now.


0
 

Author Comment

by:TCSD
ID: 8193122
Thanks for the wonderful explanation and sorry for troubling U!
Well Good Night!
0
 

Author Comment

by:TCSD
ID: 8193138
Thanks for the wonderful explanation and sorry for troubling U!
Well Good Night!
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question