What is the default operation of the '=' operator?
I have a class, Number
, which represents a double with two digits after the dot. Before I overloaded the =
operator I ran some tests and got a little confused:
int main(int argc, char **argv) {
Number *w = new Number(1.111);
Number *q = new Number(3.444);
*w = *q;
std::cout << w->GetNumber() <<std::endl;
delete q;
std::cout << w->GetNumber() <<std::endl;
Number e(5.555);
Number t = e;
std::cout <<t.GetNumber() <<std::endl;
}
The output was
3.44
3.44
5.55
What is the default action of '=' on user defined objects when '=' is not overloaded?
I was under the impression that when writing:
*w = *q;
w
points 开发者_如何学Pythonto q
(like in Java). However, in my example I deleted q
and w
still had the correct values.
Anyway, I got same results when I made assignments without overloading =
and with overloading =
.
The default operation of the assignment operator is memberwise assignment:
class Foo
{
int i;
std::string s;
Bar b;
public:
Foo& operator=(const Foo& that)
{
i = that.i;
s = that.s;
b = that.b;
return *this;
}
};
If that's exactly what you need, you don't have to overload operator=
manually.
If you have pointer members, only the pointers are copied, not the pointees, which can wreak havoc. Either use RAII types like std::vector
in that case or disable copying by declaring the copy constructor and the assignment operator private
or by inheriting from boost::noncopyable
.
Note that Number t = e;
does not call the assignment operator, because there isn't yet any object to assign to. Instead, the copy constructor is called, which does memberwise copy construction by default:
Foo(const Foo& that) : i(that.i), s(that.s), b(that.b)
{
}
Since you will probably ask: the thing after the colon is called an initializer list. It cannot be overstated that initialization and assignment are two very different concepts in C++.
It makes a copy of the object (deep copy) i.e. the q
object's contents are copied into w
. If you have not provided your own copy constructor - assignment operator pair then compiler will automatically generate one for you which copies each element of the source object to the elements of the destination object. Once this copy is created, it doesn't matter what you do with the original object.
*p = *q is equivalent to
(*p).operator=(*q);
The default assignment operator does the following: (I tried putting it in short but I can't beat the standard in terms of accuracy and conciseness, hence quoting it)
The implicitly-defined copy assignment operator for class X performs memberwise assignment of its subobjects. The direct base classes of X are assigned first, in the order of their declaration in the base-specifierlist, and then the immediate nonstatic data members of X are assigned, in the order in which they were declared in the class definition. Each subobject is assigned in the manner appropriate to its type:
— if the subobject is of class type, the copy assignment operator for the class is used (as if by explicit qualification; that is, ignoring any possible virtual overriding functions in more derived classes);
— if the subobject is an array, each element is assigned, in the manner appropriate to the element type;
— if the subobject is of scalar type, the built-in assignment operator is used.
As you can see, the left hand side object does not start referring to the right hand side object.
Default operator =
perform memberwise copy of the object to the destination.
*w = *q
assign the value of *q
to *w
;
w = q
makes w point to the same object as q, but it leaks w.
精彩评论