I have some confusion with this "Can a object be passed as value to the copy constructor"
The compiler clearly rejects this, which means it is not possible.
Can you help me understand this?
class Dummy{
Dummy(Dummy dummy){ // This is not possible
}
};
Then why is it said that "Copy constructor will lead to recursive calls when pass by value is used."
This is because in order to pass by value, you need to COPY the object. Therefore, you are passing in a copy of the object, in the definition of how to copy it.
Effectively what really happens if this trap is not there, is your copy constructor will call your copy constructor to create a copy, which will call your copy constructor to create a copy, which will call your copy constructor to create a copy, ...
No.
As the error says, it will lead to recursive calls of the copy constructor. The copy constructor is used to copy an object. You need to make a copy of an object when it is passed by value.
So, if you could have such a constructor, you would need to invoke the copy constructor to copy the object you pass to the copy constructor, ad infinitum.
The standard specifically says (12.1/10 Constructors):
A copy constructor for a class X is a constructor with a first parameter of type X& or of type const X&
So it can't take a value parameter - it must be a reference.
If you think about if for a moment, it should be clear why: to pass a value parameter, the compiler must make a copy... It needs to invoke the copy constructor to do so.
When a parameter is given by value, the compiler needs to copy an object first (in order create the instance which will be the argument). So for your copy constructor to be called, the compiler needs to make a copy of the object in advance.
Usually the copy constructors are defined in such a way:
Dummy(const Dummy& dummy)
{
// This is possible
}
This way, you don't ask for a separate copy of the object for the constructor, you just give a reference to an existing copy (and promise not to change that copy as well).
Then why is it said that "Copy constructor will lead to recursive calls when pass by value is used."
Because in order to pass an object to that copy constructor by value, you might need to copy-construct it first (because the passed-by-value parameter is a temporary copy of the original object passed).
Though the answer was already given, I just wanted to clarify, since I see the same questions repeated.
Dummy(Dummy dummy); is not a copy constructor. Copy constructor can either be of form Dummy(const Dummy&); or Dummy(Dummy&); The original one is clearly prohibited by the Standard.
Then you are asking:
Then why is it said that "Copy
constructor will lead to recursive
calls when pass by value is used."
Diagnostic message is not mandated by the standard, rather your compiler chose those words to explain why it couldn't possibly work.
Related
Why must a copy constructor's parameter be passed by reference?
Because if it's not by reference, it's by value. To do that you make a copy, and to do that you call the copy constructor. But to do that, we need to make a new value, so we call the copy constructor, and so on...
(You would have infinite recursion because "to make a copy, you need to make a copy".)
Because pass-by-value would invoke the copy constructor :)
The alternative to pass-by-reference is pass-by-value. Pass-by-value is really pass-by-copy. The copy constructor is needed to make a copy.
If you had to make a copy just to call the copy constructor, it would be a conundrum.
(I think the infinite recursion would occur in the compiler and you'd never actually get such a program.)
Besides rational reasons, it's forbidden by the standard in §12.8/3:
A declaration of a constructor for a
class X is ill-formed if its first
parameter is of type (optionally cv-
qualified) X and either there are no
other parameters or else all other
parameters have default arguments.
It would be infinitely recursive if you passed it in by value
whenever you call a function (example: int f(car c))
which takes its arguments other than built-in data types (here car)
a requirement to copy the actual object supplied by the caller
to the variable in the called function's parameter.
example:
car carobj;
f(carobj);
that is, copy carobj to c.
carobj needs to be copied to the parameter c in function f.
To achieve copying, the copy constructor is called.
In this case, function f called using pass by value or in other words, function f is declared to take pass by value.
If function f takes pass by reference, then its declaration is
int f(car &c);
In this case,
car carobj;
f(carobj);
does not need a copy constructor.
In this case, c becomes the alias of carobj.
Using the above 2 scenarios, for your clarity I am summarizing them as:
If a function is declared to take a parameter as value of a object, then the copy constructor of the object is called.
If a function is declared to take a parameter as "pass by reference", the parameter becomes an alias of the object supplied by the caller. No need of a copy constructor!
Now the question is why pass by reference is required. If copy constructor accepts reference, the receiving variable become aliases of supplied object. Hence, no need of copy constructor (in this case, call to itself) to copy the value in caller supplied object to copy constructor's variable in argument list.
Otherwise, if copy constructor takes the caller supplied object as value, i.e. pass by value, then it needs the copy constructor of the given object; hence, to get the supplied object from caller into our function itself (in this case the copy constructor) we need to call the copy constructor, which is nothing but calling the same function during function declaration.
That's the reason for passing a reference to a copy constructor.
It is necessary to pass object as reference and not by value because if you pass it by value its copy is constructed using the copy constructor.This means the copy constructor would call itself to make copy.This process will go on until the compiler runs out of memory.
It is very essential to pass objects as reference. If an object is passed as value to the Copy Constructor then its copy constructor would call itself, to copy the actual parameter to the formal parameter.
Thus an endless chain of call to the copy constructor will be initiated. This process would go on untill the system run out of memory.
Hence, in a copy constructor, the parameter should always be passed as reference.
If its not passed by reference then it would pass by value. If the argument is passed by value, its copy constructor would call itself to copy the actual parameter to formal parameter. This process would go on until the system runs out of memory.
So, we should pass it by reference , so that copy constructor does not get invoked.
A copy constructor defines what copying means,So if we pass an object only (we will be passing the copy of that object) but to create the copy we will need a copy constructor, Hence it leads to infinite recursion.
So, A copy constructor must have a reference as an argument.
Why C++ provide a copy constructor? The assignment operator can do the same task. Is there any advantage of copy constructor over assignment operator?
Stuff you can do with a copy constructor that you can't do (either easily or at all) with the assignment operator:
Copy classes that don't have a default constructor. For example, if a class represents an open file, you might not be able to construct one without passing it a file name to open.
Copy classes that have an expensive default constructor. Maybe the constructor allocates a lot of memory, which will then be released as soon as you use the assignment operator to copy a new state into the object.
Pass an instance of the class by value. This is kind of the original purpose of the copy constructor. In C, if you pass a struct by value, the compiler just does a bitwise copy of the struct so the receiving function has a local copy that it can modify without affecting the caller. But C++ recognizes that a bitwise copy is not the best way to copy most objects, so it lets you write your own copy constructor (and the default copy behavior is different too, since class members may have custom copy constructors).
Copy a class that contains references, because you can't reassign a reference after the class has already been constructed. The copy constructor and assignment operator just do different things where references are concerned. The copy constructor initializes the reference to point to the same object that the reference points to in the instance that is being copied; the assignment operator actually copies the value of the referenced object.
Copy a class with const members. (Note that a class can have a default constructor but still have const members.)
With or without a copy constructor, you still have to initialize a new object to a stable initial state, which the assignment operator can then update later.
While you can certainly do that without a copy constructor, having a copy constructor helps to optimize a new object's initialization, by setting it to copy another object's state up front, without requiring you to first initialize the new object to a default state and then have a separate assignment reset that state afterwards. This way, you can set the new object's state in 1 operation instead of 2 operations.
Yes, the two are different. You can't always just implement your copy constructor as
Foo(const Foo& f) {
*this = f;
}
The assignment operator assumes that you have a valid, fully constructed object. The copy constructor makes no such assumptions. This means that, depending on your class, the assignment operator may try to clear whatever data is on the object before re-initializing. Or may even repurpose the data already on the object.
Take this example.
Jack and John are twins.
You could say this is Jack and that is Jack.
But although John is the spitting image of Jack, he ain't no Jack.
When you use the assignment operator you can refer to the exact object in memory (returning *this) or provide some custom behavior.
When you use the copy constructor you want to create another object in memory that has a copy of the properties of the original object, but that can evolve in a different direction.
If you want a deeper answer I think this blog post is better.
Assignment is a little more tricky than initialization, because what
we are essentially doing is destructing the existing object and then
re-constructing it with new values. In a more complex class, you might
need to free various resources and then re-allocate them using copies
of the resources from the object being copied. std::unique_ptr makes
our life easy here, because assigning a new instance of
std::unique_ptr to an existing std::unique_ptr object with = as above
(or by using reset()) first frees the old pointer, so releasing the
resource is handled for us automatically (this is the same reason our
class doesn’t need a destructor – when std::unique_ptr goes out of
scope as our object goes out of scope, std::unique_ptr‘s destructor is
called and the resource is freed automatically).
I have a class A with a vector<Object> object_list_ as a member variable.
I know that if I had a vector of pointers I would have needed to write a specific copy constructor to achieve a deep copy. However, in this case, as I don't have pointers, when copying an object of type A, the default copy constructor will automatically also call the copy constructors of Object or each element in object_list_ or do I have to write my own copy constructor to do that?
The default copy constructor for your class will call the default copy constructor for each member, in the order they're declared in the class. One rule of thumb is that if you don't need a special destructor, then you don't need to change the copy constructor, copy assignment, move constructor, or move assignment either. (Though deleting them may still make sense, depending on the class).
A vector's copy constructor will make a copy of its elements, using their copy constructors. If those are pointers, it will copy the pointers, which means they'll point at the same data as the origonal vector. 99% of the time this is what you want. Though very rarely you may want to replace your class' copy constructor to make the vector do something else.
It sounds like you don't need to make a copy constructor in your case.
Copy constructors of member variables are called all the way down. So if a default one was generated (and it would be in this case) then it gets called.
I know that when you call a function this way :
foo(MyClass a)
The object a is being passed by value meaning it's being copied.
My question is how is it being copied?
say my class don't have a copy constructor, so if it is passed using shallow copy than
the object may change inside the function?
Compiler automatically generates the code for the copy constructor and performs member wise copy. The copy constructor which compiler calls does member wise copy which is indeed shallow copy.
It is inadvisable to pass an object by value if a pointer in your class exists. Even if a pointer does not exist, but a dozen other data members exist, they would require a lot of time to get copied.Pass it by reference, and make it const if you dont want its value to be changed.
There are two possibilities.
First: You didn't specify a copy constructor.
In this case the default copy constructor MyClass::MyClass(MyClass const&) will be used. This will attempt to copy construct all of MyClass's member (recursively, as these may have members themselves). If any of these members is not copy constructible your default copy constructor will therefore fail as well (see next point).
Second: You declared the copy constructor private or actually deleted it (in C++11).
In this case, you will not be able to pass anything to this function, because the compiler will require access to a copy constructor, which you denied it. This will lead to compile time errors.
the compiler creates a default copy constructor.
Why must a copy constructor's parameter be passed by reference?
Because if it's not by reference, it's by value. To do that you make a copy, and to do that you call the copy constructor. But to do that, we need to make a new value, so we call the copy constructor, and so on...
(You would have infinite recursion because "to make a copy, you need to make a copy".)
Because pass-by-value would invoke the copy constructor :)
The alternative to pass-by-reference is pass-by-value. Pass-by-value is really pass-by-copy. The copy constructor is needed to make a copy.
If you had to make a copy just to call the copy constructor, it would be a conundrum.
(I think the infinite recursion would occur in the compiler and you'd never actually get such a program.)
Besides rational reasons, it's forbidden by the standard in §12.8/3:
A declaration of a constructor for a
class X is ill-formed if its first
parameter is of type (optionally cv-
qualified) X and either there are no
other parameters or else all other
parameters have default arguments.
It would be infinitely recursive if you passed it in by value
whenever you call a function (example: int f(car c))
which takes its arguments other than built-in data types (here car)
a requirement to copy the actual object supplied by the caller
to the variable in the called function's parameter.
example:
car carobj;
f(carobj);
that is, copy carobj to c.
carobj needs to be copied to the parameter c in function f.
To achieve copying, the copy constructor is called.
In this case, function f called using pass by value or in other words, function f is declared to take pass by value.
If function f takes pass by reference, then its declaration is
int f(car &c);
In this case,
car carobj;
f(carobj);
does not need a copy constructor.
In this case, c becomes the alias of carobj.
Using the above 2 scenarios, for your clarity I am summarizing them as:
If a function is declared to take a parameter as value of a object, then the copy constructor of the object is called.
If a function is declared to take a parameter as "pass by reference", the parameter becomes an alias of the object supplied by the caller. No need of a copy constructor!
Now the question is why pass by reference is required. If copy constructor accepts reference, the receiving variable become aliases of supplied object. Hence, no need of copy constructor (in this case, call to itself) to copy the value in caller supplied object to copy constructor's variable in argument list.
Otherwise, if copy constructor takes the caller supplied object as value, i.e. pass by value, then it needs the copy constructor of the given object; hence, to get the supplied object from caller into our function itself (in this case the copy constructor) we need to call the copy constructor, which is nothing but calling the same function during function declaration.
That's the reason for passing a reference to a copy constructor.
It is necessary to pass object as reference and not by value because if you pass it by value its copy is constructed using the copy constructor.This means the copy constructor would call itself to make copy.This process will go on until the compiler runs out of memory.
It is very essential to pass objects as reference. If an object is passed as value to the Copy Constructor then its copy constructor would call itself, to copy the actual parameter to the formal parameter.
Thus an endless chain of call to the copy constructor will be initiated. This process would go on untill the system run out of memory.
Hence, in a copy constructor, the parameter should always be passed as reference.
If its not passed by reference then it would pass by value. If the argument is passed by value, its copy constructor would call itself to copy the actual parameter to formal parameter. This process would go on until the system runs out of memory.
So, we should pass it by reference , so that copy constructor does not get invoked.
A copy constructor defines what copying means,So if we pass an object only (we will be passing the copy of that object) but to create the copy we will need a copy constructor, Hence it leads to infinite recursion.
So, A copy constructor must have a reference as an argument.