Rule A12-8-1 (required, implementation, automated)
Move and copy constructors shall move and respectively copy base classes and data members of a class, without any side effects.
Rationale
It is expected behavior that the move/copy constructors are only used to move/copy the object of the class type and possibly set moved-from object to a valid state. Move and copy constructors of an object are frequently called by STL algorithms and containers, so they are not supposed to provide any performance overhead or side effects that could affect moving or copying the object. Note: Class members that are not essential for a class invariant may not need to be copied (e.g. caches, debug information).
Example
// $Id: A12-8-1.cpp 303582 2018-01-11 13:42:56Z michal.szczepankiewicz $
#include <cstdint>
#include <utility>
class A
{
public:
// Implementation
A(A const& oth) : x(oth.x) // Compliant
{
}
private:
std::int32_t x;
};
class B
{
public:
// Implementation
B(B&& oth) : ptr(std::move(oth.ptr)) // Compliant
{
oth.ptr = nullptr; // Compliant - this is not a side-effect, in this
// case it is essential to leave moved-from object
// in a valid state, otherwise double deletion will
// occur.
}
~B() { delete ptr; }
private:
std::int32_t* ptr;
};
class C
{
public:
// Implementation
C(C const& oth) : x(oth.x)
{
// ...
x = x % 2; // Non-compliant - unrelated side-effect
}
private:
std::int32_t x;
};
class D
{
public:
explicit D(std::uint32_t a) : a(a), noOfModifications(0) {}
D(const D& d) : D(d.a) {} // compliant, not copying the debug information
// about number of modifications
void SetA(std::uint32_t aa)
{
++noOfModifications;
a = aa;
}
std::uint32_t GetA() const noexcept
{
return a;
}
private:
std::uint32_t a;
std::uint64_t noOfModifications;
};
See also
MISRA C++ 2008 [7]: Rule 12-8-1 A copy constructor shall only initialize its base classes and the nonstatic members of the class of which it is a member.
HIC++ v4.0 [9]: 12.5.3 Ensure that a user defined move/copy constructor only moves/copies base and member objects.
JSF December 2005 [8]: AV Rule 77: A copy constructor shall copy all data members and bases that affect the class invariant (a data element representing a cache, for example, would not need to be copied).