User-defined copy and move assignment operators should use user-defined no-throw swap function
User-defined copy and move assignment operators should use user-defined no-throw swap function.
A naive copy or move assignment operator that is implemented without using a swap function might follow the pattern in this code:
class A{
//...
A & operator=(const A & rhs)
{
if (this != &rhs) // check for self assignment
{
// release resource in lhs
// Allocate resource for modified lhs
// Copy or move the resources from rhs to lhs
}
return *this;
}
private:
//resources
int* mArray;
};To resolve these issues, utilize user-defined swap functions that do
not raise exceptions. Consider this
pattern:
class A{
//...
A & operator=(A rhs)
{
Swap(*this,rhs);
}
friend void Swap(A& lhs, A& rhs) noexcept{
//...
}
private:
//resources
int* mArray;
};noexcept function Swap. This
Swap function might be implemented by utilizing the
std::swap function. The benefits of this pattern are:
Strong exception safety: This implementation of the copy or move assignment
operator takes a temporary copy of the right operand by using the copy or move
constructor and swaps the temporary copy with the left operand. Because the move and
swap functions must be noexcept, only the copy operation might
raise an exception. If this operator raises an exception, only the temporary copy of
the right operand might be invalidated. The state of the right or the left operand
remains untouched.
Code reuse: In this implementation, the copy or move assignment operator reuses
the copy or move constructor. The class-specific swap function can
also be reused for implementing other algorithms.
Efficiency: By eliminating the check against self-assignment, the operator is more efficient.
To implement a copy or move assignment operator, use user-defined
noexcet swap functions.
Polyspace® flags a copy or move assignment operator if it does not contain at least one
call to a user-defined swap function. Polyspace identifies functions that have these signatures as swap functions:
void T::swap(T&) or void [N::]swap(T&,
T&). The first signature represents a member function of class
T that takes one argument. The second signature represents a nonmember
or static function in the namespace N that takes two arguments. The name
swap can be case-insensitive and prefixed or postfixed by
underscores.
If you expect a rule violation but do not see it, refer to the documentation for Polyspace Bug Finder™ or Polyspace Bug Finder Server™.
| Group: Special member functions |
| Category: Advisory, Automated |
AUTOSAR C++14 Rule A12-8-2 (Polyspace Bug Finder)