> Also you could define the move-assignment operator
You could.
But if you are in the least bit sensible, don't define foundation operations of your own
unless you have to.
Define them if and only if the operations implicitly declared (and synthesized where required) by the implementation would be semantically incorrect or inadequate.
As far as possible, not this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
struct A
{
A( const std::string& s = "" ) : str(s) {}
// user-defined destructor, copy constructor, move constructor,
// copy assignment, move assignment
~A() noexcept {}
A( const A& that ) : str(that.str) {}
A( A&& that ) noexcept : str( std::move(that.str) ) {}
A& operator= ( const A& that ) { str = that.str ; return *this ; }
A& operator= ( A&& that ) noexcept
{ str = std::move(that.str) ; return *this ; }
// ...
std::string str ;
};
|
But this:
1 2 3 4 5 6 7 8 9 10 11
|
struct B
{
B( const std::string& s = "" ) : str(s) {}
// imlicitly declared destructor, copy constructor, move constructor,
// copy assignment, move assignment
// ...
std::string str ;
};
|
B is simpler and more readable, has a much higher chance of being correct and is at least as efficient. If we later modify the class (say add a new non-static member
std::vector<int> numbers ;
), we just have to add the member in B. In A, the user-defined copy and move operations would have to be carefully rewritten.
> I have tryed with non-member function, but the compiler says that the + operator must have 1 or 0 arguments. Why this?
A non-member
operator+()
must have either one (for the unary + operator) or two (for the binary + operator) arguments.
A member
operator+()
must have either zero (for the unary + operator) or one (for the binary + operator) explicit argument.
> the return value is stored in the stack of the main(),
> will this value remain in memory until at the end of the main?
For a function that returns by value (that is does not return a reference), the result of the function is a "pure rvalue" or
prvalue. It need not be stored anywhere at all (it need not be associated with an object). If it is stored somewhere as an anonymous temporary object, that temporary is destroyed as soon as it is no longer required.