-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Split various rules and fix formatting
- Split A6-5-3 and A6-5-4 - Split A12-8-1 and A12-8-2 - Split M5-0-4 and M5-0-5 - Split M5-0-14 and M5-0-15 - Split M7-3-2 and M7-3-3 - Fix code formatting
- Loading branch information
1 parent
efbb018
commit 99f19d7
Showing
13 changed files
with
230 additions
and
256 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
> **Rule A12-8-2 (advisory, implementation, automated)** | ||
> | ||
> User-defined copy and move assignment operators should use user-defined | ||
> no-throw swap function. | ||
## Rationale | ||
|
||
Using a non-throwing swap operation in the copy and move assignment operators | ||
helps to achieve Strong Exception Safety. Each assignment operator is also | ||
simplified because it does not require check for assignment to itself. | ||
|
||
## Example | ||
|
||
```cpp | ||
// $Id: A12-8-2.cpp 289436 2017-10-04 10:45:23Z michal.szczepankiewicz $ | ||
#include <cstdint> | ||
#include <utility> | ||
class A | ||
{ | ||
public: | ||
A(const A& oth) | ||
{ | ||
// ... | ||
} | ||
A(A&& oth) noexcept | ||
{ | ||
// ... | ||
} | ||
A& operator=(const A& oth) & // Compliant | ||
{ | ||
A tmp(oth); | ||
Swap(*this, tmp); | ||
return *this; | ||
} | ||
A& operator=(A&& oth) & noexcept // Compliant | ||
{ | ||
A tmp(std::move(oth)); | ||
Swap(*this, tmp); | ||
return *this; | ||
} | ||
static void Swap(A& lhs, A& rhs) noexcept | ||
{ | ||
std::swap(lhs.ptr1, rhs.ptr1); | ||
std::swap(lhs.ptr2, rhs.ptr2); | ||
} | ||
|
||
private: | ||
std::int32_t* ptr1; | ||
std::int32_t* ptr2; | ||
}; | ||
|
||
class B | ||
{ | ||
public: | ||
B& operator=(const B& oth) & // Non-compliant | ||
{ | ||
if (this != &oth) | ||
{ | ||
ptr1 = new std::int32_t(*oth.ptr1); | ||
ptr2 = new std::int32_t( | ||
*oth.ptr2); // Exception thrown here results in | ||
// a memory leak of ptr1 | ||
} | ||
|
||
return *this; | ||
|
||
} | ||
B& operator=(B&& oth) & noexcept // Non-compliant | ||
{ | ||
if (this != &oth) | ||
{ | ||
ptr1 = std::move(oth.ptr1); | ||
ptr2 = std::move(oth.ptr2); | ||
oth.ptr1 = nullptr; | ||
oth.ptr2 = nullptr; | ||
} | ||
|
||
return *this; | ||
} | ||
|
||
private: | ||
std::int32_t* ptr1; | ||
std::int32_t* ptr2; | ||
}; | ||
``` | ||
|
||
## See also | ||
|
||
HIC++ v4.0 [9]: 12.5.6 Use an atomic, non-throwing swap operation to | ||
implement the copy and move assignment operators |
Oops, something went wrong.