I have a class.
class Books
{
private:
int m_books;
public:
Books(int books=0)
{
m_books = books;
}
Books(const Books &source) //Here is what I don't understand.
{
m_books = source.m_books;
}
};
I can't understand why it has to be Books(const Books &source), and not Books(const Books source).
When you have
Books(const Books &source)
the source is passed by reference. When you have
Books(const Books source)
it would have been passed by value. But to pass by value you are the copy constructor. So to avoid an infinite recursion, the copy constructor must accept a reference.
Books(const Books &source)
means that a reference is passed, instead of the actual variable (as in pass-by-value, as in the case of primitives such as int or char).
In this case, since you are building a copy constructor, you don't want to make modification to the object whose reference is passed in, so the argument signature is prefixed with const (this guarantees that the argument being passed in is immutable)
(Note, mostly importantly: pass-by-value here would introduce infinite recursion - see #AProgrammer's answer) Aside from that, it also would be unnecessarily expensive to pass in source by value (meaning: make a copy of the entire source when the copy constructor is called), we just use a reference instead.
Additional reading you might be interested in: C++ Pass by Reference vs. Value
What you're looking at is called the copy constructor. The reason why you should pass an object by a reference is because if you pass it by a value then a copy of the object has to be constructed, so it would have to call the copy constructor again. And again. And again ...
So book is passed by reference instead of copied by value.
Using a reference means that there's no copy involved. If you had:
Books(const Books source)
Then the argument the caller passes would have to be copied to source. If you use a reference instead, no copy is made. This provides better performance. With small amounts of data it doesn't matter much, because it's a simple class with no large amount of data. But with more complex classes, copying can be expensive. Using references avoids that problem.
However, in the case of copy constructors, avoiding a copy is vital. Not for performance reasons, but by the fact that copying involves a copy constructor. When the copy constructor gets called, another copy would have to be made if a reference was not used. That means another call to a copy constructor. There, yet another copy would have to be made. Yet another call to a copy constructor.
As you can imagine, this would result in an infinite amount of copy constructor calls. By using a reference this situation is avoided.
Read about copy constructors: http://www.cplusplus.com/articles/y8hv0pDG/
It is passing in a reference to the Books source object. That it all.
I hope this helps.
Related
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).
When passing objects to functions there is the choice to pass arguments either by value or by const&. Especially when the object is possibly expensive to create and it is internally mutated or used to initialize another object the recommendation is to pass the object by value. For example:
class Foo {
std::vector<std::string> d_strings;
public:
Foo(std::vector<std::string> strings): d_strings(std::move(strings)) {}
// ...
};
The conventional approach would be to declare the strings parameter as std::vector<std::string> const& and copy the argument. The value argument to the constructor above also needs to be copied!
Why is it preferable to pass by value rather than pass by const&?
When passing the strings argument by const& there is a guaranteed copy: there is no other way to get hold a, well, copy of the argument other than copying it. The question becomes: how is that different when passing by value?
When the argument is passed by value the strings object is clearly used nowhere else and its content can be moved. Move construction of expansive to copy objects may still be comparatively cheap. For example, in the case of the std::vector<std::string> the move is just copying a few pointers to the new object and setting a few pointers to indicate to the original object that it shouldn't release anything.
There is still the need to create the argument, though. However, the creation of the argument may be elided without creating a new object. For example
Foo f(std::vector<std::string>{ "one", "two", "three" });
will create a vector with three strings and construction of the argument to the Foo construct is most likely elided. In the worst case, the argument is constructed by moving the temporary vector, avoiding a copy, too.
There are, of course, cases where a copy still needs to be created. For example, in the case
std::vector<std::string> v{ "one", "two", "three" };
Foo f(v);
The argument is created by a copy. The ready made copy is then moved to the member. In this case pass by const& would have been better because only a copy construction would have been needed rather than a copy construction (to create the argument) followed by a move construction (to create the member) being done.
That is, passing by value enables possibly eliding a copy entirely and just having a move. In the worst case, when the argument needs to be copied anyway, an additional move needs to be performed. Since the move is generally assumed to be a cheap operation the expectation is that overall pass by value for objects which need to be transferred results in better performance.
The statement
Arguments should be passed by value when used to initialize another object
Is true, starting with C++11, thanks to the introduction of move semantic.
It could be generalized to:
When a function needs a copy of one of its arguments, pass it by value.
This is actually well detailed in the "Want Speed? Pass by Value." article.
The outline is that, since your function will need a copy of the argument anyway, it is better to have this copy handled at the call-site instead of inside the called function. This is because, if the object that the function needs a copy is an Rvalue, it is only known at call site, thus enabling move optimization: the calling context is well aware that the object is expiring, and thus can move-it into the copy that the function requires. Now, if the copy was to be made inside the function itself, the notion that the source object (in the calling context) was an Rvalue would not be forwarded up to the actual place of the copy, loosing the opportunity for a move.
I want to ask one simple question which is making me confuse.
for example if I write in argument there is no reference &. but in the second case I have used & with rectangleType&, I am having confusion why we use this & when we can do it without this &. Where is this necessary and why we use it. My question is not about copy constructor.
rectangleType rectangleType::operator+
(const rectangleType rectangle)
Case 2:
rectangleType rectangleType::operator+
(const rectangleType& rectangle)
When you pass an object like rectangleType (or any other type) by value, you're making a copy of that object. This means:
Any changes made to the object by the function are not seen by the caller, since the changes are made on a copy, not the original object.
The act of copying the object incurs a performance cost.
Copying the object may not even be possible for some types.
So, pass by reference whenever:
You want the function to be able to modify the original object.
You want the code to run faster by not having to make a copy.
The object you're passing doesn't have a public copy constructor.
Pass by const reference whenever you don't need the function to be able to modify the original object.
For user-defined types, this essentially boils down to "pass by reference wherever possible."
How can you state that your question is not about copy construction if the answere is about it?
With a const reference no copy is made, this can be crucial for very large objects
There are classes wich explicitely dont provide a copy constructor, this way you can still pass them around.
So to conclude: You get benefits without disadvantages.
In the first method, it will receive a (complete) instance of rectangleType, that will be created using the copy constructor just to be passed as a parameter.
In the second method, it will receive a reference to an already existing instance; no copy will be made.
If I change it to void setOutputFormat(ostream& out, int decimal_places),
with a call by reference, it works. I don't understand why though?
What is the difference between a struct and a class, besides struct members are by default public, and class members are by default private?
You're right that there is no difference between class and struct, except the default private vs private.
The problem here is that ostream doesn't have a copy constructor, so you can't pass it by value.
When you attempt to pass the ostream by value, you attempt to make a copy of the stream, which is not valid because stream objects are noncopyable, that is, they do not define a copy constructor. When you pass the stream by reference, however, the function receives a modifiable alias to the ostream instance. Take for instance:
void increment(int n) {
// Increment local copy of value.
++n;
}
int x = 5;
increment(x);
// x is still 5.
Versus:
void increment(int& n) {
// Increment value itself.
++n;
}
int x = 5;
increment(x);
// x is now 6.
So passing the stream by reference is the only way that makes sense, since you want setOutputFormat to modify the original stream in-place. Hope this clarifies the issue somewhat.
As other said, you're trying to create a copy of a noncopyable object (the stream), which results in that error.
In C++ when you pass a var as a parameter, you make a copy of it (opposed to C#, where, for reference types, you're always implicitly passing a reference to it).
By default C++ provides a bitwise copy constructor for every class, but often it's not what is required: think, for example, to a class that owns a resource handle: if you make a perfect clone of an object of that type you'll have two class who think to own such resource, and both will try to destroy it at their destruction, which clearly isn't nice.
Because of this, C++ lets you provide a copy constructor for each class, which is called when a copy of an object has to be created. Since for many objects (streams included) creating copies isn't desired (because it makes no sense, because it's not convenient or because the trouble isn't worth the work) often the copy constructor is disabled (by marking it as private or protected), and you can't create copies of such objects.
Moreover, in general you must be careful with assignments and copies by value with object belonging to complicated class hierarchies, because you may incur in object slicing and other subtle problems. Actually, it's common practice to block copy and assignment in classes intended to be base classes.
The solution, in most cases (including yours) is to pass such objects by reference, thus avoiding making copies at all; see #Jon Purdy's answer for an example.
By the way, often even with copyable objects (e.g. std::strings) it's better to just pass references, to avoid all the work associated with copying; if you're passing a reference just for the sake of efficiency but you don't want to have your object modified, the best solution usually is a const reference.
Copies are also used in some other places in C++; I advise you to have a look at wikipedia page about copy constructors to understand a bit better what's going on, but, over all, to grab a C++ book and read it: C# is different from C++ in a lot of ways, and there are many fake-similarities that may confuse you.
I have defined the following class:
class Action
{
public:
Action(){ _bAllDone = false; }
void AddMove( Move & m );
private:
std::deque<Move> _todo;
bool _bAllDone;
};
The member AddMove is defined as follows:
void Action::AddMove( Move & m )
{
_todo.push_back( m );
}
I noted that without the reference argument to this function the Copy Constructor was called twice, whereeas with a reference argument it was called only once. Is calling a Copy Constructor only once instead of twice a good reason to use a reference argument?
The deque class in STL is supposed to maintain a copy of the element you pass to its push_back method. That is where one copy constructor comes from.
If you get rid of the reference in addMove(), you will first get a copy of the parameter (and thus one invocation of the copy constructor), and then when you push back, you will get a second copy.
The dual invocation of the copy constructor is wasteful so the reference is preferable. However, you should declare the parameter of addMove() as a const reference, to indicate to the caller that the element will not be modified. Under such an assurance (assuming you don't break it), it is safe to pass the object by reference without worrying and without paying the penalty of an object copy.
Seems like a big advantage to me. Things could get very slow if you are performing many adds iteratively. The actual amount of work would depend on the definition of Move and its copy constructor. And small changes could have severe effects on performance. Bite either way, passing by copy would still be twice as much work.
The overall effect of this will depend on how much of the entire processing is spend on this operation. Do it once, you'll never notice; do it a few thousand times, and it may be significant. However as a general principle, avoid copying data where you can safely reference it, especially since in this case there is no particular clarity or complexity issue - it is as easy to make it fast as it is to make it slow, so why would you make it slow?
It must be a reference, otherwise you'll be incurring an unnecessary (and potentially incorrect) copy of the argument. It should also be const, otherwise you'll unnecessarily restrict your callers.
Note also that names with a leading underscore are reserved to the language implementation, so your program is actualy "undefined".
HTH