• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 389
  • Last Modified:

Copy constructor

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
TCSD
Asked:
TCSD
  • 4
  • 3
  • 2
  • +2
1 Solution
 
DarthNemesisCommented:
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
 
KashraCommented:
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
 
TrueIdiotCommented:
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
KashraCommented:
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
 
TCSDAuthor Commented:
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
 
DarthNemesisCommented:
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
 
DarthNemesisCommented:
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
 
keitha1Commented:
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
 
TCSDAuthor Commented:

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
 
keitha1Commented:
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
 
TCSDAuthor Commented:
Thanks for the wonderful explanation and sorry for troubling U!
Well Good Night!
0
 
TCSDAuthor Commented:
Thanks for the wonderful explanation and sorry for troubling U!
Well Good Night!
0

Featured Post

Become an Android App Developer

Ready to kick start your career in 2018? Learn how to build an Android app in January’s Course of the Month and open the door to new opportunities.

  • 4
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now