Consider the f开发者_C百科ollowing code?
I was wondering, if I change it from (Function body still the same)
error_code& operator|=(const error_code &e)
to
error_code operator|=(const error_code &e)
Is there any potential bug that might possible occur? The only difference I see is, it will perform an extra copy operation, other than that, no big deal.
So, should I just stick to return by reference, or it doesn't matter?
class error_code {
public:
error_code() : hi(0), lo(0) {}
error_code(__int64 lo) : hi(0), lo(lo) {}
error_code(__int64 hi, __int64 lo) : hi(hi), lo(lo) {}
// How about return by copy?
error_code& operator|=(const error_code &e) {
this->hi |= e.hi;
this->lo |= e.lo;
return *this;
}
__int64 hi;
__int64 lo;
};
error_code operator|(const error_code& e0, const error_code& e1) {
return error_code(e0.hi | e1.hi, e0.lo | e1.lo);
}
int main() {
error_code e0(1);
error_code e1(2);
e0 |= e1;
}
Is there any potential bug that might possible occur?
Yes. This won't work as expected anymore:
(ec |= x) = y;
Now, this is a silly piece of code, no doubt about that, but
- it does work for other types and
- there might be other cases where this difference matters.
For example, if your class error_code
will have member functions modifying the object they are invoked for, then these will modify a temporary object if you return by copy instead of reference:
(ec |= x).normalize(); // whatever "normalizing" error code means...
It would mean that anything you then do with the returned object would not affect the original object any more. And the other way round - the returned object would never reflect changes done to the original object. This is a typical issue of value vs identity. You are keeping a copy of the object's value, but you're losing its identity.
精彩评论