C++ copy constructor called multiple times - c++

I was trying to understand the basics of copy constructors and came across the following example.
#include <iostream>
using namespace std;
class Line
{
public:
int getLength() const;
Line( int len ); // simple constructor
Line( const Line &obj); // copy constructor
~Line(); // destructor
private:
int *ptr;
};
// Member functions definitions including constructor
Line::Line(int len)
{
cout << "Normal constructor allocating ptr" << endl;
// allocate memory for the pointer;
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj)
{
cout << "Copy constructor allocating ptr." << endl;
ptr = new int;
*ptr = *obj.ptr; // copy the value
}
Line::~Line()
{
cout << "Freeing memory!" << endl;
delete ptr;
}
int Line::getLength() const
{
return *ptr;
}
void display(Line obj)
{
cout << "Length of line : " << obj.getLength() <<endl;
}
// Main function for the program
int main( )
{
Line line1(10);
Line line2 = line1; // This also calls copy constructor
//display(line1);
//display(line2);
return 0;
}
When executed, it gives the following output.
Normal constructor allocating ptr
Copy constructor allocating ptr.
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
Freeing memory!
The copy constructor is called only once, in the Line line2 = line1; But it seems that the copy constructor is being called twice. So I commented out the
display(line1); and display(line2); . After that the output is something like this.
Normal constructor allocating ptr
Copy constructor allocating ptr.
Freeing memory!
Freeing memory!
So the problem(I don't know if I should call it a problem or its a default standard in C++) is with the display function. Could it be because the display() function automatically creates a copy of the object its processing and that's why the copy constructor is called twice for each instance? Kindly clarify. Thanks.

with void display(Line obj), you pass object by value, so create copy.
You should pass by (const) reference to avoid the copies:
void display(const Line& obj)

Could it be because the display() function automatically creates a copy of the object its processing and that's why the copy constructor is called twice for each instance? Kindly clarify. Thanks.
That is exactly what is happening. If you pass an object into a function by value, it will be copied prior to the function call executing. If you do not wish this to happen, use a pointer or a reference.

Related

Why is the copy constructor called after the simple constructor is called? [duplicate]

This question already has answers here:
Why is the copy constructor called when we pass an object as an argument by value to a method?
(3 answers)
Closed 2 years ago.
I was trying to understand the copy constructor, and read this (https://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm) tutorialspoint article about it. However, I'm having trouble understanding when the copy constructor was called in the code below. Doesn't Line line(10) only call the Simple constructor, which then allocates memory for ptr and sets the value at ptr to 10?
Is it because we passed line as an argument to display? So does passing an object as an argument always invoke the copy constructor?
#include <iostream>
using namespace std;
class Line {
public:
int getLength( void );
Line( int len ); // simple constructor
Line( const Line &obj); // copy constructor
~Line(); // destructor
private:
int *ptr;
};
// Member functions definitions including constructor
Line::Line(int len) {
cout << "Normal constructor allocating ptr" << endl;
// allocate memory for the pointer;
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj) {
cout << "Copy constructor allocating ptr." << endl;
ptr = new int;
*ptr = *obj.ptr; // copy the value
}
Line::~Line(void) {
cout << "Freeing memory!" << endl;
delete ptr;
}
int Line::getLength( void ) {
return *ptr;
}
void display(Line obj) {
cout << "Length of line : " << obj.getLength() <<endl;
}
// Main function for the program
int main() {
Line line(10);
display(line);
return 0;
}
Which prints out:
Normal constructor allocating ptr
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
Doesn't Line line(10) only call the Simple constructor
Yes.
Is it because we passed line as an argument to display?
Yes.
So does passing an object as an argument always invoke the copy constructor?
Not necessarily. For example, some types don't have constructors so copying them won't invoke a constructor. Furthermore, if you pass an rvalue, then move constructor may be invoked instead. Or if the type of the argument is different from the type of the parameter, then a converting constructor or conversion operator may be invoked.
If the parameter is a reference (of same type, so no conversion is involved), then no constructor is invoked.

C++ copy constructor calling other constructors [duplicate]

This question already has answers here:
Why is the copy constructor called when we pass an object as an argument by value to a method?
(3 answers)
Closed 4 years ago.
I have this code. I'm not that proficient in C++, so I'm going to ask several questions:
#include <iostream>
using namespace std;
class Line {
public:
int getLength( void );
Line( int len ); // simple constructor
Line( const Line &obj); // copy constructor
~Line(); // destructor
private:
int *ptr;
};
// Member functions definitions including constructor
Line::Line(int len) {
cout << "Normal constructor allocating ptr" << endl;
// allocate memory for the pointer;
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj) {
cout << "Copy constructor allocating ptr." << endl;
ptr = new int;
cout<<&obj<<endl;
*ptr = *obj.ptr; // copy the value
}
Line::~Line(void) {
cout << "Freeing memory!" << endl;
delete ptr;
}
int Line::getLength( void ) {
return *ptr;
}
void display(Line obj) {
cout << "Length of line : " << obj.getLength() <<endl;
}
// Main function for the program
int main() {
int a = 10;
cout<<&a<<endl;
Line line(a);
display(line);
return 0;
}
Here I don't see where we call copy contructor.
Destructor is being called twice. Where is the second object is being created?
Line::Line(const Line &obj) receives address of a as a parameter? I guess not. But why? a by itself is not an instance of Line, so why function accepts that?
What would be the difference between Line::Line(const Line &obj) and Line::Line(const Line obj)
And could you please explain this *ptr = *obj.ptr; . From here i know only lhs, which dereferences ptr (aka sets value of an object). But I didn't get what's in rhs?
I'd appreciate if you explain with less technical terms and more examples, for clarity
Above code outputs this:
0x7fff692196a4
Normal constructor allocating ptr
Copy constructor allocating ptr.
0x7fff69219698
Length of line : 10
Freeing memory!
Freeing memory!
Here for some reason default constructor is called. I don't see any place where we create object without parameter (aka that goes to default constructor)
I don't see any place either! How can you be so sure the default constructor is called? In fact, your class is not constructible using a default constructor because there isn't one. If you try this:
Line l;
It won't compile since there is no default constructor.
Destructor is being called twice. Where is the second object is being created?
It this line:
display(line);
You function receives a value. To have a value both in your main and your display function, you have to copy it somehow. Passing line will copy it from your main to your function.
Line::Line(const Line &obj) receives address of a as a parameter? I guess not. But why? a by itself is not an instance of Line, so why function accepts that?
No. This is a reference. The copy constructor receive a reference from other context to copy it.
What would be the difference between Line::Line(const Line &obj) and Line::Line(const Line obj)
One is a reference, the other is passing by value (a copy, move or other construction). If the copy constructor had to receive a value, how would you copy the value into the copy constructor? The copy constructor must receive a reference.
And could you please explain this *ptr = *obj.ptr; . From here i know only lhs, which dereferences ptr (aka sets value of an object). But I didn't get what's in rhs?
I don't know what you mean by rhs and lhs, is not in the code you posted. But indeed, *ptr = *obj.ptr will set the value from the integer pointed by obj.ptr into the variable pointed by this->ptr.
I recommend getting a good C++ book and follow a tutorial that will teach you the basics.

is copy constructor called automatically even when there isn't any object to be copied?

I found this piece of code on the net:
#include <iostream>
using namespace std;
class Line {
public:
int getLength( void );
Line( int len ); // simple constructor
Line( const Line &obj); // copy constructor
~Line(); // destructor
private:
int *ptr;
};
// Member functions definitions including constructor
Line::Line(int len) {
cout << "Normal constructor allocating ptr" << endl;
// allocate memory for the pointer;
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj) {
cout << "Copy constructor allocating ptr." << endl;
ptr = new int;
*ptr = *obj.ptr; // copy the value
}
Line::~Line(void) {
cout << "Freeing memory!" << endl;
delete ptr;
}
int Line::getLength( void ) {
return *ptr;
}
void display(Line obj) {
cout << "Length of line : " << obj.getLength() <<endl;
}
// Main function for the program
int main( ) {
Line line(10);
display(line);
return 0;
}
the result of executing this code was:
Normal constructor allocating ptr
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
I can't understand why copy constructor is called when there is no object that is passed as an argument to copy constructor?
also, while debugging, I understand that a destructor is called after function main finished. why it is called and why it is called after function main terminated??
thanks,
void display(Line obj) {
This function takes its parameter by value. This means that passing this parameter to this function will copy it. This is where your copy constructor gets called, when main() calls display().
If you change this function so that it takes its parameter by reference:
void display(Line &obj) {
You will find that the copy constructor no longer gets called, from your sample program.
You will find more information about passing parameters by value versus reference in your C++ book.
The function display takes it's argument by value, hence the copy constructor is called. If that is not wanted, pass it by reference - Line & obj. Better yet, call it by const reference - const Line & obj. But in the latter case, the member function you call inside of display would have to be const also.
The argument in display():
void display(Line obj)
Invokes the copy constructor, as a new object is being made in the argument of the function. Therefore, any object of class Line that you pass to this function will be copied and used as a perameter for the function body.
You invoke this function in the following line:
display(line);
As a result, a copy of line is made in display(). To avoid this, reference an object of class Line instead. Change the way the argument is passed in the function header to:
void display(Line &obj)
This way, you are only referencing the object, hence, not making a copy of it. Therefore, the copy constructor will not be invoked here.

copy constructor being called multiple times c++

I was going over through tutorials on copy constructor in c++ offered by tutorialspoint.com http://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm
In one of their sample codes:
#include <iostream>
using namespace std;
class Line
{
public:
int getLength(void);
Line(int len); // simple constructor
Line(const Line &obj); // copy constructor
~Line(); // destructor
private:
int *ptr;
};
// Member functions definitions including constructor
Line::Line(int len)
{
cout << "Normal constructor allocating ptr" << endl;
// allocate memory for the pointer;
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj)
{
cout << "Copy constructor allocating ptr." << endl;
ptr = new int;
*ptr = *obj.ptr; // copy the value
}
Line::~Line(void)
{
cout << "Freeing memory!" << endl;
delete ptr;
}
int Line::getLength(void)
{
return *ptr;
}
void display(Line obj)
{
cout << "Length of line : " << obj.getLength() << endl;
}
// Main function for the program
int main()
{
Line line1(10);
Line line2 = line1; // This also calls copy constructor
display(line1);
display(line2);
return 0;
}
and the output was
Normal constructor allocating ptr
Copy constructor allocating ptr.
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
Freeing memory!
I don't understand the output. To me it show be that the normal constructor is called for line1, then one copy constructor for line2 and then 2*"freeing memory" for the 2 objects
The output I thought was:
Normal constructor allocating ptr
Copy constructor allocating ptr.
Length of line : 10
Length of line : 10
Freeing memory!
Freeing memory!
q.1> why copy constructor is called multiple times initially
q.2>4 times "freeing memory" and that too one in between, I am really confused, could you help me out.
Thanks
This is simply constructed:
Line line1(10);
and as you recognized, this is where your copy constructor is called:
Line line2 = line1;
So far so good. Now take a look at the signature to display:
void display(Line obj);
This is what we call pass-by-value. Pass-by-value is a parameter form that causes a new object to be constructed from the one passed in. Hence, the two calls here:
display(line1);
display(line2);
are both calling the copy constructors to get line1 and line2 into the function-local obj variable.
This is roughly equivalent to this:
// Instead of calling display, this happens instead:
{ // Entering a new scope
Line obj = line1;
cout << "Length of line : " << obj.getLength() << endl;
} // Exiting scope
{ // Entering a new scope
Line obj = line2;
cout << "Length of line : " << obj.getLength() << endl;
} // Exiting scope
obj is it's own object now, independent of the lifetimes of line1 or line2, and when obj goes out of scope, as it does at the end of the function, it's destructor is called. This would explain the four total calls to the destructor: one for the original simply constructed object (line1), one for the copy constructed object (line2), and two for the two function-local objs.
If you want to avoid a copy like you indicated in your question, use pass-by-reference.
void display(Line obj) calls copy constructor for its parameter,
you may use const reference to avoid the copy (void display(const Line& obj)).
The example goes like this:
Line line1(10); // Normal constructor allocating ptr
Line line2 = line1; // Copy constructor allocating ptr
display(line1); /* Copy constructor allocating ptr, because function is this:
void display(Line obj);
This will make a copy of the object going into the method, just as if it were an int, for example. If you want to eliminate this copy, change to
void display(const Line& obj);
which passes a reference.
*/
/* Next the funtion is called and prints
Length of line : 10
Then the destructor of the copy is called at the end of the function, before it returns.
Freeing memory!
*/
display(line2);/* Next the same pattern is repeated with the second function call:
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
*/
return 0; /* Finally, both line1 and line2 are destructed:
Freeing memory!
Freeing memory!
*/
q.1> why copy constructor is called multiple times initially
You call display(line), display(line2). void display(Line obj) is defined to receive as a parameter Line object, so every time you call for display, the object is copied for that function (like if you were sending integer to a function, its value would be copied so that if the function modified that integer it wouldn't effect anything but the scope of the function). In order to reduce the number of copy constructors you can define display as void display(Line& obj). But then pay attention that every modification made on obj will be reflected in the main().
q.2>4 times "freeing memory" and that too one in between, I am really
confused, could you help me out.
Two times as you expected (one for line and another for line2) and two more for the object which was copied to display function. Once the flow of display is executed, it destructs all the local objects and function parameter is considered to be a local object.

How in this copy constructors is called?

I am reading copy constructors for the first time. Here is the link from which I am reading it: http://www.tutorialspoint.com/cplusplus/cpp_copy_constructor.htm
Now, in their first example, in the output, they have written this:
Normal constructor allocating ptr
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
I just want to know, how exactly the copy constructor is getting called here? In the main function, they have written it as:
#include <iostream>
using namespace std;
class Line
{
public:
int getLength( void );
Line( int len ); // simple constructor
Line( const Line &obj); // copy constructor
~Line(); // destructor
private:
int *ptr;
};
// Member functions definitions including constructor
Line::Line(int len)
{
cout << "Normal constructor allocating ptr" << endl;
// allocate memory for the pointer;
ptr = new int;
*ptr = len;
}
Line::Line(const Line &obj)
{
cout << "Copy constructor allocating ptr." << endl;
ptr = new int;
*ptr = *obj.ptr; // copy the value
}
Line::~Line(void)
{
cout << "Freeing memory!" << endl;
delete ptr;
}
int Line::getLength( void )
{
return *ptr;
}
void display(Line obj)
{
cout << "Length of line : " << obj.getLength() <<endl;
}
// Main function for the program
int main( )
{
Line line(10);
display(line);
return 0;
}
So, it's just Line line(10) which will call the constructor for setting length. Why exactly will the copy constructor be called? Wont' the constructor be called when we pass it an actual object of class Line?
You are passing line by value to display.
When you pass an object to a function by value, a copy of the object is created on the stack. In your case, the obj parameter of the display function is created calling the copy constructor of the class Line.
When you passed solid object as display(Line) function parameter, copy constructor is called because in C++ arguments are passed by value when you pass solid object. So when you passed Line object into function, copy constructor is called to create object copy from existing one. To avoid copying you need to pass parameters by reference or pointer(smart or normal).
display is defined like:
void display(Line obj)
This is pass by value and not pass by reference. A copy must be made which is why the copy constructor is called.
Your function display is defined like:
void display(Line obj)
This is a call-by-value, and in the case of call-by-valuethe copy of the argument is made, not the actual object is passed. Hence when your function is called copy constructoris invoked.
If you want to avoid it, pass parameter by reference or pointer.
Change the definition of Display from void display(Line obj) to
void display(Line *obj)
and in mainchange the function call from display(line); to display(&line);