There is a scenario where when I get a reply from an API via a callback and I need to move the objects in reply to my class member variable to proceed processing. Will the following code achieve the objective:
class Obj {
public:
Obj (unit32_t& x, std::string& x, int& data)
{}
... lot of variable .. no pointers
};
class A
{
public:
A(Obj& r):pvtmemVarTyOfObj(0,"",0) {}
private:
Obj pvtmemVarTyOfObj ;
};
void A::GetResponse(Obj&& resp)
{
//pvtmemVarTyOfObj = std::forward<Obj>(std::move(resp));
pvtmemVarTyOfObj = std::move(resp);
}
Will this code actually move resp to pvtmemVarTyOfObj member variable? Just to ensure that no-copy should be done as it will lead to huge processing cost?
Just use std::move(resp) here. You know for sure that resp is a rvalue reference, hence you always want to move.
If Obj was a template parameter, you would need to use std::forward<Obj>(resp). Because in this case Obj&& would be an universal reference, which could be an rvalue or lvalue reference and std::forward deduces whether resp can be moved from or not.
Whether in the end a copy or move is performed depends on the assignment operators of pvtmemVarTyOfObj's class. If it does only contain plain data and no allocated resources (e.g. via pointers), move can't provide any benefits.
The move constructor, and the move assignment operator, only do what they are
programmed to do, by you the programmer. Technically, they can be designed to
do anything, but that is not advisable.
Rather, they should be designed to make the target object indistinguishable from
the source object, while leaving the source object in a valid state.
If you do not provide a move operation yourself, one will be synthesized by means
of member-wise move.
Move for fundamental types such as int, just do a copy.
Move for many library-types, such as std::vector, std::string and
std::unique_ptr, are designed, by the library-implementor, to transfer
ownership of resources, such as memory.
This means, that for a stack-allocated POD, there just is no way to avoid
a copy. If the operation is performance-critical, and a copy is just unacceptable,
the solution could be to not have a stack-allocated POD in the first place, for
example by sticking the object in a std::unique_ptr.
Another option could be to only ever have the target object, and let others 'access'
that object through pointers or references.
Related
I made a class for a function's argument to delegate its validation and also for function overloading purposes.
Throwing from constructor guarantees that the object will either be constructed in a valid state or will not be constructed at all. Hence, there is no need to introduce any checking member functions like explicit operator bool() const.
// just for exposition
const auto &certString = open_cert();
add_certificate(cert_pem{certString.cbegin(), certString.cend()}); // this will either throw
// or add a valid certificate.
// cert_pem is a temporary
However, there are issues which I don't see a appealing solution for:
Argument-validation class might itself be made non-persistent - to be used only for validation as a temporary object. But what about classes that are allowed to be persistent? That is living after function invocation:
// just for exposition
const auto &certString = open_cert();
cert_pem cert{certString.cbegin(), certString.cend()}; // allowed to throw
cert_pem moved = std::move(cert); // cert invalidated
cert_pem cert_invalid = std::move(cert); // is not allowed to throw
add_certificate(cert_invalid); // we lost the whole purpoce
I can see several ways to treat this without introducing state-checking (thus declaring a class stateful) functions:
Declare object "unusable" after move. - A really simple recipe for disaster
Declare move constructor and assignment operator deleted. Allow only copy - Resources might be very expensive to copy. Or even not possible if using a PIMPL idiom.
Use heap allocation when need an object to be persistent - this looks like most obvious. But has an unnecessary penalty on performance. Especially when some class has as members several such objects - there will be several memory allocations upon construction.
Here is a code example for 2):
/**
* Class that contains PEM certificate byte array.
* To be used as an argument. Ensures that input certificate is valid, otherwise throws on construction.
*/
class cert_pem final
{
public:
template <typename IterT>
cert_pem(IterT begin, IterT end)
: value_(begin, end)
{
validate(value_);
}
const std::vector<uint8_t>& Value() const noexcept(false)
{
return value_;
}
cert_pem (const cert_pem &) = default;
cert_pem & operator=(const cert_pem &) = default;
cert_pem (cert_pem &&) = delete;
cert_pem & operator=(cert_pem &&) = delete;
private:
/**
* \throws std::invalid_argument
*/
static void Validate(const std::vector<uint8_t>& value) noexcept(false);
static void ValidateNotEmpty(const std::vector<uint8_t>& value) noexcept(false);
private:
std::vector<uint8_t> value_;
};
Is there another way to handle this problem without these shortcomings? Or will I have to choose one of the above?
I think that with argument-validating classes a good way would be to not allow it to be persistent - only temporary object is allowed. But I am not sure if it is possible in C++.
You are trying to maintain two invariants at once, and their semantics are in conflict. The first invariant is the validity of the certificate. The second is for memory management.
For the first invariant, you decided that there can be no invalid constructed object, but for the second, you decided that the object can be either valid or unspecified†. This is only possible because the deallocation has a check somewhere.
There is no way around this: you either add a check for the first or you decouple the invariants. One way of decoupling them is to follow the design of std::lock_guard
cert c = open_cert(); // c is guaranteed to not have memory leaks and is movable
{
cert_guard cg{c}; // cg is guaranteed to be valid, but cg is non-movable
}
But wait, you might ask, how do you transfer the validity to another cert_guard?
Well, you can't.
That is the semantics you chose for the first invariant: it is valid exactly during the lifetime of the object. That is the entire point.
† Unspecified and invalid as far as the certificate is concerned.
The question aims to design a type such that:
an object of the type always satisfies a given invariant
an object of the type is "usable" as a non-temporary
The question then makes a leap from (2) to ask that the type be movable. But it need not be: copy and move operations could be defined as deleted. The question fails to motivate why the move operations are necessary. If that is a need, it comes from an unstated requirement. A non-movable class can be emplaced in a map, returned from a function, and used in many other ways. It admittedly can be more painful to use, but it can be used.
So that's one option that's not listed: define copy and move operations as deleted.
Otherwise, let's assume we do want:
an object of the type always satisfies a given invariant
the type is movable
This is not in conflict. Every copyable class is movable, and copying is a valid strategy here. Remember that move operations allow a "potentially smarter" copy, by allowing the source to be mutated. There are still two C++ objects, and it is still a logical copy, but with an assumption that the source won't be needed anymore in its current state (so you can steal from it!). There is no difference in the C++ interface, only in the totally unchecked documented behavior of the type after a move operation.
Defining move operations as deleted gives you a copyable class. This is your second option listed. Assigning from an xvalue (cert_pem moved = std::move(cert)) will still compile, but will not invalidate the source. It will still be considered movable by the language. The trade-off is as you note, copies can be expensive. Note that PIMPL authors can give their types copy operations, that's a choice they make about what the interface of the type should be, and the idiom doesn't prevent it.
The third choice is a version of the second. By putting values behind a shared_ptr, one can make an expensive-to-copy type cheap to copy. But we still rely on copy as the strategy for move.
The first choice amounts to weakening the invariant in (1). A moved-from object satisfying a different set of invariants than a normal object is very typical in C++. It is annoying, but in many cases it is the best we can do. When only one object can exist satisfying the invariant (think: non-null unique_ptr) the moved-from object must violate it.
The accepted answer amounts to my first option combined with delayed construction: define copy and move operations as deleted. Creating the guard can throw if the object was moved-from. The guard is just the type maintaining the invariant, and it is non-movable. We can delay its construction because such types are difficult to manage. We do that by keeping an object that knows enough about how to construct it. This strategy exists in other forms (emplace functions and piecewise_construct constructors to construct objects in their eventual place, factory functions to construct the object at will, etc.).
However, the description in the accepted answer leaves a bit to be desired, in my opinion. The desire is to maintain the invariant while being movable (this is assumed). Being movable doesn't require that the moved-from object satisfy an invariant or be unspecified. That's a choice the author of the type makes, and what choices are available is exactly the question, by my reading of it. Although the example given only implicated memory, and the first answer mentioned memory, my reading of the question was more general: maintaining invariants in movable classes.
Knowing that all copyable classes are movable, that move is a "smart" copy, and that there are two objects in and after a move operation will help in understanding why there's such limited options here. One has to leave that source object in some state.
My advice is to embrace the radioactive moved-from object. That's the approach in the standard library, and defaulted move operations will obey that more often than not. For such types, there must be some "empty" state for moved-from objects, so all types are effectively optional and a default constructor can also be defined to get an object in that empty state.
Have found comparable questions but not exactly with such a case.
Take the following code for example:
#include <iostream>
#include <string>
#include <vector>
struct Inner
{
int a, b;
};
struct Outer
{
Inner inner;
};
std::vector<Inner> vec;
int main()
{
Outer * an_outer = new Outer;
vec.push_back(std::move(an_outer->inner));
delete an_outer;
}
Is this safe? Even if those were polymorphic classes or ones with custom destructors?
My concern regards the instance of "Outer" which has a member variable "inner" moved away. From what I learned, moved things should not be touched anymore. However does that include the delete call that is applied to outer and would technically call delete on inner as well (and thus "touch" it)?
Neither std::move, nor move semantics more generally, have any effect on the object model. They don't stop objects from existing, nor prevent you from using those objects in the future.
What they do is ask to borrow encapsulated resources from the thing you're "moving from". For example, a vector, which directly only stores a pointer some dynamically-allocated data: the concept of ownership of that data can be "stolen" by simply copying that pointer then telling the vector to null the pointer and never have anything to do with that data again. It's yielded. The data belongs to you now. You have the last pointer to it that exists in the universe.
All of this is achieved simply by a bunch of hacks. The first is std::move, which just casts your vector expression to vector&&, so when you pass the result of it to a construction or assignment operation, the version that takes vector&& (the move constructor, or move-assignment operator) is triggered instead of the one that takes const vector&, and that version performs the steps necessary to do what I described in the previous paragraph.
(For other types that we make, we traditionally keep following that pattern, because that's how we can have nice things and persuade people to use our libraries.)
But then you can still use the vector! You can "touch" it. What exactly you can do with it is discoverable from the documentation for vector, and this extends to any other moveable type: the constraints emplaced on your usage of a moved-from object depend entirely on its type, and on the decisions made by the person who designed that type.
None of this has any impact on the lifetime of the vector. It still exists, it still takes memory, and it will still be destructed when the time comes. (In this particular example you can actually .clear() it and start again adding data to a new buffer.)
So, even if ints had any sort of concept of this (they don't; they encapsulate no indirectly-stored data, and own no resources; they have no constructors, so they also have no constructors taking int&&), the delete "touch"ing them would be entirely safe. And, more generally, none of this depends on whether the thing you've moved from is a member or not.
More generally, if you had a type T, and an object of that type, and you moved from it, and one of the constraints for T was that you couldn't delete it after moving from it, that would be a bug in T. That would be a serious mistake by the author of T. Your objects all need to be destructible. The mistake could manifest as a compilation failure or, more likely, undefined behaviour, depending on what exactly the bug was.
tl;dr: Yes, this is safe, for several reasons.
std::move is a cast to an rvalue-reference, which primarily changes which constructor/assignment operator overload is chosen. In your example the move-constructor is the default generated move-constructor, which just copies the ints over so nothing happens.
Whether or not this generally safe depends on the way your classes implement move construction/assignment. Assume for example that your class instead held a pointer. You would have to set that to nullptr in the moved-from class to avoid destroying the pointed-to data, if the moved-from class is destroyed.
Because just defining move-semantics is a custom way almost always leads to problems, the rule of five says that if you customize any of:
the copy constructor
the copy assignment operator
the move constructor
the move assignment operator
the destructor
you should usually customize all to ensure that they behave consistently with the expectations a caller would usually have for your class.
When should I declare my function as:
void foo(Widget w);
as opposed to:
void foo(Widget&& w);?
Assume this is the only overload (as in, I pick one or the other, not both, and no other overloads). No templates involved. Assume that the function foo requires ownership of the Widget (e.g. const Widget& is not part of this discussion). I'm not interested in any answer outside the scope of these circumstances. (See addendum at end of post for why these constraints are part of the question.)
The primary difference that my colleagues and I can come up with is that the rvalue reference parameter forces you to be explicit about copies. The caller is responsible for making an explicit copy and then passing it in with std::move when you want a copy. In the pass by value case, the cost of the copy is hidden:
//If foo is a pass by value function, calling + making a copy:
Widget x{};
foo(x); //Implicit copy
//Not shown: continues to use x locally
//If foo is a pass by rvalue reference function, calling + making a copy:
Widget x{};
//foo(x); //This would be a compiler error
auto copy = x; //Explicit copy
foo(std::move(copy));
//Not shown: continues to use x locally
Other than forcing people to be explicit about copying and changing how much syntactic sugar you get when calling the function, how else are these different? What do they say differently about the interface? Are they more or less efficient than one another?
Other things that my colleagues and I have already thought of:
The rvalue reference parameter means that you may move the argument, but does not mandate it. It is possible that the argument you passed in at the call site will be in its original state afterwards. It's also possible the function would eat/change the argument without ever calling a move constructor but assume that because it was an rvalue reference, the caller relinquished control. Pass by value, if you move into it, you must assume that a move happened; there's no choice.
Assuming no elisions, a single move constructor call is eliminated with pass by rvalue.
The compiler has better opportunity to elide copies/moves with pass by value. Can anyone substantiate this claim? Preferably with a link to gcc.godbolt.org showing optimized generated code from gcc/clang rather than a line in the standard. My attempt at showing this was probably not able to successfully isolate the behavior: https://godbolt.org/g/4yomtt
Addendum: why am I constraining this problem so much?
No overloads - if there were other overloads, this would devolve into a discussion of pass by value vs a set of overloads that include both const reference and rvalue reference, at which point the set of overloads is obviously more efficient and wins. This is well known, and therefore not interesting.
No templates - I'm not interested in how forwarding references fit into the picture. If you have a forwarding reference, you call std::forward anyway. The goal with a forwarding reference is to pass things as you received them. Copies aren't relevant because you just pass an lvalue instead. It's well known, and not interesting.
foo requires ownership of Widget (aka no const Widget&) - We're not talking about read-only functions. If the function was read-only or didn't need to own or extend the lifetime of the Widget, then the answer trivially becomes const Widget&, which again, is well known, and not interesting. I also refer you to why we don't want to talk about overloads.
What do rvalue usages say about an interface versus copying?
rvalue suggests to the caller that the function both wants to own the value and has no intention of letting the caller know of any changes it has made. Consider the following (I know you said no lvalue references in your example, but bear with me):
//Hello. I want my own local copy of your Widget that I will manipulate,
//but I don't want my changes to affect the one you have. I may or may not
//hold onto it for later, but that's none of your business.
void foo(Widget w);
//Hello. I want to take your Widget and play with it. It may be in a
//different state than when you gave it to me, but it'll still be yours
//when I'm finished. Trust me!
void foo(Widget& w);
//Hello. Can I see that Widget of yours? I don't want to mess with it;
//I just want to check something out on it. Read that one value from it,
//or observe what state it's in. I won't touch it and I won't keep it.
void foo(const Widget& w);
//Hello. Ooh, I like that Widget you have. You're not going to use it
//anymore, are you? Please just give it to me. Thank you! It's my
//responsibility now, so don't worry about it anymore, m'kay?
void foo(Widget&& w);
For another way of looking at it:
//Here, let me buy you a new car just like mine. I don't care if you wreck
//it or give it a new paint job; you have yours and I have mine.
void foo(Car c);
//Here are the keys to my car. I understand that it may come back...
//not quite the same... as I lent it to you, but I'm okay with that.
void foo(Car& c);
//Here are the keys to my car as long as you promise to not give it a
//paint job or anything like that
void foo(const Car& c);
//I don't need my car anymore, so I'm signing the title over to you now.
//Happy birthday!
void foo(Car&& c);
Now, if Widgets have to remain unique (as actual widgets in, say, GTK do) then the first option cannot work. The second, third and fourth options make sense, because there's still only one real representation of the data. Anyway, that's what those semantics say to me when I see them in code.
Now, as for efficiency: it depends. rvalue references can save a lot of time if Widget has a pointer to a data member whose pointed-to contents can be rather large (think an array). Since the caller used an rvalue, they're saying they don't care about what they're giving you anymore. So, if you want to move the caller's Widget's contents into your Widget, just take their pointer. No need to meticulously copy each element in the data structure their pointer points to. This can lead to pretty good improvements in speed (again, think arrays). But if the Widget class doesn't have any such thing, this benefit is nowhere to be seen.
Hopefully that gets at what you were asking; if not, I can perhaps expand/clarify things.
The rvalue reference parameter forces you to be explicit about copies.
Yes, pass-by-rvalue-reference got a point.
The rvalue reference parameter means that you may move the argument, but does not mandate it.
Yes, pass-by-value got a point.
But that also gives to pass-by-rvalue the opportunity to handle exception guarantee: if foo throws, widget value is not necessary consumed.
For move-only types (as std::unique_ptr), pass-by-value seems to be the norm (mostly for your second point, and first point is not applicable anyway).
EDIT: standard library contradicts my previous sentence, one of shared_ptr's constructor takes std::unique_ptr<T, D>&&.
For types which have both copy/move (as std::shared_ptr), we have the choice of the coherency with previous types or force to be explicit on copy.
Unless you want to guarantee there is no unwanted copy, I would use pass-by-value for coherency.
Unless you want guaranteed and/or immediate sink, I would use pass-by-rvalue.
For existing code base, I would keep consistency.
Unless the type is a move-only type you normally have an option to pass by reference-to-const and it seems arbitrary to make it "not part of the discussion" but I will try.
I think the choice partly depends on what foo is going to do with the parameter.
The function needs a local copy
Let's say Widget is an iterator and you want to implement your own std::next function. next needs its own copy to advance and then return. In this case your choice is something like:
Widget next(Widget it, int n = 1){
std::advance(it, n);
return it;
}
vs
Widget next(Widget&& it, int n = 1){
std::advance(it, n);
return std::move(it);
}
I think by-value is better here. From the signature you can see it is taking a copy. If the caller wants to avoid a copy they can do a std::move and guarantee the variable is moved from but they can still pass lvalues if they want to.
With pass-by-rvalue-reference the caller cannot guarantee that the variable has been moved from.
Move-assignment to a copy
Let's say you have a class WidgetHolder:
class WidgetHolder {
Widget widget;
//...
};
and you need to implement a setWidget member function. I'm going to assume you already have an overload that takes a reference-to-const:
WidgetHolder::setWidget(const Widget& w) {
widget = w;
}
but after measuring performance you decide you need to optimize for r-values. You have a choice between replacing it with:
WidgetHolder::setWidget(Widget w) {
widget = std::move(w);
}
Or overloading with:
WidgetHolder::setWidget(Widget&& widget) {
widget = std::move(w);
}
This one is a little bit more tricky. It is tempting choose pass-by-value because it accepts both rvalues and lvalues so you don't need two overloads. However it is unconditionally taking a copy so you can't take advantage of any existing capacity in the member variable. The pass by reference-to-const and pass by r-value reference overloads use assignment without taking a copy which might be faster
Move-construct a copy
Now lets say you are writing the constructor for WidgetHolder and as before you have already implemented a constructor that takes an reference-to-const:
WidgetHolder::WidgetHolder(const Widget& w) : widget(w) {
}
and as before you have measured peformance and decided you need to optimize for rvalues. You have a choice between replacing it with:
WidgetHolder::WidgetHolder(Widget w) : widget(std::move(w)) {
}
Or overloading with:
WidgetHolder::WidgetHolder(Widget&& w) : widget(std:move(w)) {
}
In this case, the member variable cannot have any existing capacity since this is the constructor. You are move-constucting a copy. Also, constructors often take many parameters so it can be quite a pain to write all the different permutations of overloads to optimize for r-value references. So in this case it is a good idea to use pass-by-value, especially if the constructor takes many such parameters.
Passing unique_ptr
With unique_ptr the efficiency concerns are less important given that a move is so cheap and it doesn't have any capacity. More important is expressiveness and correctness. There is a good discussion of how to pass unique_ptr here.
When you pass by rvalue reference object lifetimes get complicated. If the callee does not move out of the argument, the destruction of the argument is delayed. I think this is interesting in two cases.
First, you have an RAII class
void fn(RAII &&);
RAII x{underlying_resource};
fn(std::move(x));
// later in the code
RAII y{underlying_resource};
When initializing y, the resource could still be held by x if fn doesn't move out of the rvalue reference. In the pass by value code, we know that x gets moved out of, and fn releases x. This is probably a case where you would want to pass by value, and the copy constructor would likely be deleted, so you wouldn't have to worry about accidental copies.
Second, if the argument is a large object and the function doesn't move out, the lifetime of the vectors data is larger than in the case of pass by value.
vector<B> fn1(vector<A> &&x);
vector<C> fn2(vector<B> &&x);
vector<A> va; // large vector
vector<B> vb = fn1(std::move(va));
vector<C> vc = fn2(std::move(vb));
In the example above, if fn1 and fn2 don't move out of x, then you will end up with all of the data in all of the vectors still alive. If you instead pass by value, only the last vector's data will still be alive (assuming vectors move constructor clears the sources vector).
One issue not mentioned in the other answers is the idea of exception-safety.
In general, if the function throws an exception, we would ideally like to have the strong exception guarantee, meaning that the call has no effect other than raising the exception. If pass-by-value uses the move constructor, then such an effect is essentially unavoidable. So an rvalue-reference argument may be superior in some cases. (Of course, there are various cases where the strong exception guarantee isn't achievable either way, as well as various cases where the no-throw guarantee is available either way. So this is not relevant in 100% of cases. But it's relevant sometimes.)
Choosing between by-value and by-rvalue-ref, with no other overloads, is not meaningful.
With pass by value the actual argument can be an lvalue expression.
With pass by rvalue-ref the actual argument must be an rvalue.
If the function is storing a copy of the argument, then a sensible choice is between pass-by-value, and a set of overloads with pass-by-ref-to-const and pass-by-rvalue-ref. For an rvalue expression as actual argument the set of overloads can avoid one move. It's an engineering gut-feeling decision whether the micro-optimization is worth the added complexity and typing.
One notable difference is that if you move to an pass-by-value function:
void foo(Widget w);
foo(std::move(copy));
compiler must generate a move-constructor call Widget(Widget&&) to create the value object. In case of pass-by-rvalue-reference no such call is needed as the rvalue-reference is passed directly to the method. Usually this does not matter, as move constructors are trivial (or default) and are inlined most of the time.
(you can check it on gcc.godbolt.org -- in your example declare move constructor Widget(Widget&&); and it will show up in assembly)
So my rule of thumb is this:
if the object represents a unique resource (without copy semantics) I prefer to use pass-by-rvalue-reference,
otherwise if it logically makes sense to either move or copy the object, I use pass-by-value.
From what I understand I'm able to "disable" copying and assigning to my objects by defining private copy constructor and assignment operator:
class MyClass
{
private:
MyClass(const MyClass& srcMyClass);
MyClass& operator=(const MyClass& srcMyClass);
}
But what's the usage of this?
Is it considered a bad practice?
I would appreciate if you could describe the situation, in which it would be reasonable / useful to "disable" assignment and copy constructor in this way.
It's useful when it doesn't make sense for your object to be copied. It is definitely not considered bad practice.
For instance, if you have a class that represents a network connection, it's not meaningful to copy that object. Another time you may want a class to be noncopyable is if you had a class representing one player in a multiplayer game. Both these classes represent things that can't be copied in the real world, or that don't make sense to copy (a person, a connection).
Also, if you are trying to implement a Singleton, it's standard procedure to make the objects non-copyable.
Generally speaking any class that manages a resource should be none-copyable or have specialized copy semantics. The converse is true as well: any class that is non-copyable or needs specialized copy semantics is managing a resource. "Manage a resource" in the C++ lingua in practice means responsible for some space in memory, or for a connection to a network or a database, or a handle to a file, or an undo transaction, and so on.
Resource management captures quite a lot of examples. These are responsibilities that take a prefix operation, a suffix operation and possibly some action in between. Memory management, for example, involves acquiring a handle to a memory address which we'll manage, perhaps mess around with that memory, and finally release the handle (because if you love something, let it be free).
template<typename T>
struct memory {
memory(T const& val = T()) : p(new T(val)) { }
~memory() { delete p }
T& operator*() const { return *p; }
private:
T* p;
};
// ...
{
memory<int> m0;
*m0 = 3;
std::cout << *m0 << '\n';
}
This memory class is almost correct: it automatically acquires the underlying memory space and automatically releases it, even if an exception propagates some time after it acquired its resource. But consider this scenario:
{
memory<double> m1(3.14);
memory<double> m2(m1); // m2.p == m1.p (do you hear the bomb ticking?)
}
Because we didn't provide specialized copy semantics for memory, the compiler provides its own copy constructor and copy assignment. These do the wrong thing: m2 = m1 means m2.p = m1.p, such that the two pointers point at the same address. It's wrong because when m2 goes out of scope it frees its resource like a good responsible object, and when m1 then goes out of scope it too frees its resource, that same resource m2 has already freed, completing a double-delete -- a notorious undefined behaviour scenario. Moreover, in C++ it's extremely easy to make copies of an object without even noticing: a function taking its parameter by value, returning its parameter by value, or taking its parameter by reference but then calling another function which itself takes (or returns) its parameter by value ... It's easier to just assume that things will try to get copied.
All this to say that when a class' raison d'être is managing a resource then you immediately should know that you need to handle copying. You should decide
you support copying, whereas you decide what copying means: safe sharing of the resource, performing a deep copy of the underlying resource so there is no sharing whatsoever, or combining the two approaches as in copy-on-write or lazy copy. Whatever path you choose you will need to provide a specialized copy constructor and a copy assignment operator.
or you don't support any sort of copying of the resource, in which case you disable the copy constructor and the copy assignment operator.
I'd go so far and say that resource management is the only case where you disable copying or provide specialized copy semantics. This is just another perspective on The Rule of Three.
It's a pretty common practice. There are are lots of examples where copying isn't appropriate.
Let's say your object represents an open server-side socket (i.e. an incoming network connection); what would be the semantics of making a copy of that object?
when you are allowed to create instance of object only after checking like in the case of singleton u need private constructors. when constructor is called the object instance will be called and then there is no point in checking if there is another instance already. so what we do is call a member function of class from main and inside that member function check if another instance is already in the memory. if not constructor is called. else aborted.
check singleton classes or other protected classes where data of object has to be kept secured and should not be allowed to copy.
also check this : Singleton Class in C++
When you are trying to implement a singleton pattern it's perfectly acceptable to use a private constructor as it's meant to be only instantiated inside itself and from nowhere else.
Once invoked, the constructor can't be revoked. So the constructor is invoked only after checking if the singleton condition satisfied.
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.