Coding guidelines
The following list gives some general recommendations on code structure and design. By following these suggestions an uniform look-and-feel is given to the user and the general code quality is improved. As for every rule there are valid exceptions.
-
Constructor's
If your class has member variables of non-trivial type, remember to implement the following set of class methods:
- constructor
- copy constructor
- move constructor
- assignment operator
- move assignment operator
-
Inequality operator
Always implement in the inequality operator as negation of the corresponding equality operator:
bool Class::operator!=(const Class& other) const { return not (*this == other); }
-
Prefer pass-by-value for initialization methods for non-trivial member variables
If a given class methods initializes a member variable with an input argument, receive this argument by-value and then move the copied argument into the member variable. In this way, the call site can decide whether it needs to keep the initial object or not.
"If you're going to make a copy of something in a function, let the compiler do it in the parameter list."
class C
{
public:
void initialize(std::shared<C> other) // receive input by-value
{
m_pOther = std::move(other); // move object into member variable
}
private:
std::shared_ptr<C> m_pOther;
};
// on the call site
std::shared_ptr<C> pOther = std::make_shared<C>();
C myObject;
myObject.initialize(pOther); // keep pOther and initialize by copy
myObject.initialize(std::move(pOther)); // we do not need pOther any longer
-
Implement support for swap
Provide support for a non-throwing swap-function for your class as friend function:
class C
{
public:
friend void swap(C& first,C& second) noexcept
{
using std::swap;
// swap member variables
}
};
-
Use copy-and-swap idiom for assignments
Strive to implement assignment operators providing a strong exception-safety by using the copy-and-swap idiom:
Class& Class::operator=(Class rhs) // receive rhs by-value instead of by const reference
{
swap(*this,other);
return *this;
}
This idiom trades performance for exception safety as an additional copy is made. Its usage is recommended until proven to be a performance bottleneck.