Consider the following code snippet:
list<someClass>& method();
....
list<someClass> test = method();
What will the behavior of this be? Will this code:
Return a reference to the someClass instance returned by return value optimization from method(), and then perform someClass's copy constructor on the reference?
Avoid calling the copy constructor somehow?
Specifically, I have methods that are returning very large lists, and I want to avoid calling copy constructors on each return value.
EDIT: Erm, sorry, code compiles now...
The copy constructor will have to be called, because this code must make a copy: the method() function returns a reference to some object, a copy of which must be stored in the variable test.
Since you are returning a reference and not an object, there is no need for return value optimization.
If you do not want to make a copy of the list, you can make test a reference:
list<someClass>& test = method();
However, test will then refer to the original list, so any modifications made to test will also be made to the original list, and whenever the original list is destroyed, test will become invalid (which means you have to be more careful with object lifetimes).
There exists RVO. I am not sure if it applies here. Anyways it's one way to minimize copying.
http://en.wikipedia.org/wiki/Return_value_optimization
Well, you can't assign a list to someClass (unless you overloaded the assignment operator or copy constructor, and use the returned list to copy construct). If you didn't this shouldn't compile.
Looking at your code it is difficult to hazard a guess as to what you are trying to achieve here by returning the reference to a list and then making a copy of it.
Do consider the idea of returning an iterator to the list (or reference to the iterator) if possible (assuming that the list is not something local to a function etc).
Related
I am new to C++ (coming from C#) and I want to get that memory stuff right from the beginning.
In the following snipped a variable of type WorldChunkCoordinates is passed by value to the inline constructor of WorldChunk and then the passed Coordinates are assigned to WorldChunk::Coordinates, which I believe is a copy operation as well.
(copy-assignment operation?)
If my assumptions are correct then this would be kinda stupid, because I copy the instance twice. I think it would be much more performant if I would pass by value and assign by reference pointer. But WorldChunk::Coordinates is not a pointer neither a reference.
WorldChunk(WorldChunkCoordinates Coordinates) {
WorldChunk::Coordinates = Coordinates;
}
Is there a way to safe my programm from copying the instance twice?
If so, how?
Also: Is assigning by = always a copy operation by default?
And: How should I know that a specific class may have another copy assignment operation that copies by reference?
Its a known and solved problem, called initializer list (not to be confused with the container). Looks like
WorldChunk(WorldChunkCoordinates Coordinates) : Coordinates(Coordinates){}
Consider using lower case letters for variable names.
You could also use
WorldChunk(const WorldChunkCoordinates &Coordinates) : Coordinates(Coordinates){}
but it is not obvious that dereferencing is faster than copying, especially when taking compiler optimizations into account.
first of all a simple solutuion:
change your method to:
WorldChunk(const WorldChunkCoordinates& Coordinates) { WorldChunk::Coordinates = Coordinates;}
This will lead to a single assignment instruction because coordinates is a reference.
The default constructed assignment operator assigns memberwise.
The parameter of the assignment operator is (usually) a const reference to the object so that you don't copy the parameter.
By the way a little tutorial: http://www.cplusplus.com/doc/tutorial/ which is very good in my point of view.
The convention in C++ for user type function arguments is to pass by const reference (const MyType&) for input arguments, and by reference for in-out arguments (MyType&).
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.
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.
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.
Suppose I have the following code:
class some_class{};
some_class some_function()
{
return some_class();
}
This seems to work pretty well and saves me the trouble of having to declare a variable just to make a return value. But I don't think I've ever seen this in any kind of tutorial or reference. Is this a compiler-specific thing (visual C++)? Or is this doing something wrong?
No this is perfectly valid. This will also be more efficient as the compiler is actually able to optimise away the temporary.
Returning objects from a function call is the "Factory" Design Pattern, and is used extensively.
However, you will want to be careful whether you return objects, or pointers to objects. The former of these will introduce you to copy constructors / assignment operators, which can be a pain.
It is valid, but performance may not be ideal depending on how it is called.
For example:
A a;
a = fn();
and
A a = fn();
are not the same.
In the first case the default constructor is called, and then the assignment operator is invoked on a which requires a temporary variable to be constructed.
In the second case the copy constructor is used.
An intelligent enough compiler will work out what optimizations are possible. But, if the copy constructor is user supplied then I don't see how the compiler can optimize out the temporary variable. It has to invoke the copy constructor, and to do that it has to have another instance.
The difference between Rob Walker's example is called Return Value Optimisation (RVO) if you want to google for it.
Incidentally, if you want to enure your object gets returned in the most efficient manner, create the object on the heap (ie via new) using a shared_ptr and return a shared_ptr instead. The pointer gets returned and reference counts correctly.
That is perfectly reasonable C++.
This is perfectly legal C++ and any compiler should accept it. What makes you think it might be doing something wrong?
That's the best way to do it if your class is pretty lightweight - I mean that it isn't very expensive to make a copy of it.
One side effect of that method though is that it does tend to make it more likely to have temporary objects created, although that can depend on how well the compiler can optimize things.
For more heavyweight classes that you want to make sure are not copied (say for example a large bitmap image) then it is a good idea to pass stuff like that around as a reference parameter which then gets filled in, just to make absolutely sure that there won't be any temporary objects created.
Overall it can happen that simplifying syntax and making things turned more directly can have a side effect of creating more temporary objects in expressions, just something that you should keep in mind when designing the interfaces for more heavyweight objects.