aPoint = anotherPoint;
This line triggers a call of Point::operator=
(the assignment operator), which exists because the compiler generates a default implementation. This default implementation performs assignment operations for all members of the class, as well as calling Vector3::operator=
, the assignment operator of the base class. This, in turn, is a member function of Vector3
and therefore has access to all private members, which it makes copies of.
(EDIT) A quote from the C++11 Standard to back this answer:
(§12.8/28) The implicitly-defined copy/move assignment operator for a non-union class X performs memberwise copy-/move assignment of its subobjects. The direct base classes of X are assigned first, in the order of their declaration in the base-specifier-list, and then the immediate non-static data members of X are assigned, in the order in which they were declared in the class definition. Let x be either the parameter of the function or, for the move operator, an xvalue referring to the parameter. Each subobject is assigned in the manner appropriate to its type:
— if the subobject is of class type, as if by a call to operator= with the subobject as the object expression
and the corresponding subobject of x as a single function argument (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.
Some of the other (now partly deleted) answers mentioned the idea of a bitwise copy performed by the assignment operation. There is some truth in this: If your class or struct defines a POD (plain old data) type, it is for all practical purposes identical to a C struct. In that case, it can be copied by performing memcpy
, therefore you can think of the assignment operation as being basically equivalent to a bitwise copy. But the reason why this is a valid way of thinking about it is §12.8/28 above, and that applies to non-POD types as well.
Also note that from your code it is not necessarily clear that your data type is POD. You mentioned constructors and stuff in the base class: If this involves non-trivial copy constructors, assignment operators or possibly virtual functions, then your data type is no longer POD.
About the question in the comment: In order to call the base-class assignment operator from within the derived-class implementation, just call it:
struct Base
{
};
struct Derived : Base
{
Derived &operator=(const Derived &other)
{ Base::operator=(other); return *this; }
};