Classes and class hierarchies
C.109
If a resource handle has pointer semantics, provide `*` and `->`
Reason
That's what is expected from pointers. Familiarity.
Example
???
Enforcement
???
C.lambdas: Function objects and lambdas
A function object is an object supplying an overloaded () so that you can call it. A lambda expression (colloquially often shortened to "a lambda") is a notation for generating a function object. Function objects should be cheap to copy (and therefore passed by value).
Summary:
- F.10: If an operation can be reused, give it a name
- F.11: Use an unnamed lambda if you need a simple function object in one place only
- F.50: Use a lambda when a function won't do (to capture local variables, or to write a local function)
- F.52: Prefer capturing by reference in lambdas that will be used locally, including passed to algorithms
- F.53: Avoid capturing by reference in lambdas that will be used non-locally, including returned, stored on the heap, or passed to another thread
- ES.28: Use lambdas for complex initialization, especially of
constvariables
C.hier: Class hierarchies (OOP)
A class hierarchy is constructed to represent a set of hierarchically organized concepts (only). Typically base classes act as interfaces. There are two major uses for hierarchies, often named implementation inheritance and interface inheritance.
Class hierarchy rule summary:
- C.120: Use class hierarchies to represent concepts with inherent hierarchical structure (only)
- C.121: If a base class is used as an interface, make it a pure abstract class
- C.122: Use abstract classes as interfaces when complete separation of interface and implementation is needed
Designing rules for classes in a hierarchy summary:
- C.126: An abstract class typically doesn't need a user-written constructor
- C.127: A class with a virtual function should have a virtual or protected destructor
- C.128: Virtual functions should specify exactly one of
virtual,override, orfinal - C.129: When designing a class hierarchy, distinguish between implementation inheritance and interface inheritance
- C.130: For making deep copies of polymorphic classes prefer a virtual
clonefunction instead of public copy construction/assignment - C.131: Avoid trivial getters and setters
- C.132: Don't make a function
virtualwithout reason - C.133: Avoid
protecteddata - C.134: Ensure all non-
constdata members have the same access level - C.135: Use multiple inheritance to represent multiple distinct interfaces
- C.136: Use multiple inheritance to represent the union of implementation attributes
- C.137: Use
virtualbases to avoid overly general base classes - C.138: Create an overload set for a derived class and its bases with
using - C.139: Use
finalon classes sparingly - C.140: Do not provide different default arguments for a virtual function and an overrider
Accessing objects in a hierarchy rule summary:
- C.145: Access polymorphic objects through pointers and references
- C.146: Use
dynamic_castwhere class hierarchy navigation is unavoidable - C.147: Use
dynamic_castto a reference type when failure to find the required class is considered an error - C.148: Use
dynamic_castto a pointer type when failure to find the required class is considered a valid alternative - C.149: Use
unique_ptrorshared_ptrto avoid forgetting todeleteobjects created usingnew - C.150: Use
make_unique()to construct objects owned byunique_ptrs - C.151: Use
make_shared()to construct objects owned byshared_ptrs - C.152: Never assign a pointer to an array of derived class objects to a pointer to its base
- C.153: Prefer virtual function to casting