Understand what functions C + + silently writes and calls
The compiler can secretly create a default constructor, a copy constructor, a copy assignment operator, and a destructor for class.
If you do not want to use a function generated automatically by the compiler, you should explicitly deny
To dismiss a function that the compiler automatically (secretly) provides, the corresponding member function can be declared private and not implemented.
Declaring a virtual destructor for a polymorphic base class
Polymorphic (with polymorphic) base classes should declare a virtual destructor. If class has any virtual functions, it should have a virtual destructor;
The purpose of classes is not to declare a virtual destructor if it is not used as base classes, or not for polymorphism (polymorphically).
Don't let exceptions escape destructors
Destructors should never spit out exceptions. If a function called by a destructor might throw an exception, the destructor should catch any exceptions and then spit them out (not propagate) or end the program;
If the customer needs to react to an exception that is thrown during the operation of an action function, then class should provide a normal function (not in the destructor) to perform the operation.
Never call the virtual function in the construction and destruction process
Do not call the virtual function during construction and destruction, because such calls never fall to derived class (compared to the layer that currently executes constructors and destructors).
Make operator= return a reference to *this
The Assign value (Assignment) operator returns a reference to *this.
Handling "self-assignment" in operator=
Make sure that operator= has good behavior when the object is self-assigned. The techniques include comparing the addresses of "source images" and "target objects", the thoughtful sequence of statements, and Copy-and-swap;
Determines if any function behaves more than one object, and when multiple objects are the same object, its behavior is still correct.
Do not forget every ingredient when copying an object
The copying function should ensure that "all member variables within the object" and "All base class components" are duplicated;
Do not attempt to implement another copying function with one of the copying functions. It should be said that the common functions are put into the third function and are called together by two copying functions.
Make the interface easy to use correctly, not easily misused
Good interfaces are easy to use correctly and are not easily misused. You should strive to achieve these properties in all of your interfaces;
The "block misuse" approach is to establish new types, restrict operations on types, constrain object values, and eliminate client resource management tasks;
The TR1::SHARED_PTR supports custom deleter. This can prevent DLL problems and can be used to automatically unlock mutexes (mutexes) and so on.
Design class is like design type
The design of class is the design of type. Before defining a new type, be sure to consider the creation and destruction of new type objects, initialization and assignment of objects, legal values, inheritance relationships, and so on.
Prefer to replace Pass-by-value with Pass-by-reference-to-const
Replace Pass-by-value with Pass-by-reference-to-const as much as possible. The former is usually more efficient and can avoid cutting problems;
The above rules do not apply to built-in types, as well as STL iterators and function objects. For them, pass-by-value tend to be more appropriate.
When you must return an object, don't be paranoid about returning it reference
Never return pointer or reference point to a local stack object, or return reference point to a Heap-allocated object, or return pointer or reference to a local A static object may require multiple such objects at the same time.
Declaring a member variable as private
Remember to declare the member variable as private. This gives the customer access to data consistency, fine-grained access control, allowing constraints to be guaranteed, and providing class authors with full flexibility;
Protected is not more encapsulated than public.
Better replace member function with Non-member and non-friend
Rather take the Non-member non-friend function to replace the member function. This can increase encapsulation, wrap elasticity (packaging flexibility), and functional expandability.
If all parameters require type conversion, use the Non-member function
This function must be a non-member if you need to convert all the parameters of a function, including the metaphorical parameter referred to by the this pointer.
Consider writing a swap function that does not throw an exception
When Std::swap is inefficient for your type, provide a swap member function and make sure that the function does not throw an exception;
If you provide a member swap, you should also provide a non-member swap to invoke the former. For classes (not templates), please also special std::swap;
You should use the using declaration for std::swap when calling swap, and then call swap without any "namespace qualifier";
STD templates for "User Defined type" is good, but don't try to add something new to STD in Std.
Delay the occurrence of variable definitions whenever possible
Postpone the occurrence of variable definitions as much as possible. This can increase the clarity of the program and improve the efficiency of the program.
Try to do less transformational action
If you can, try to avoid the transition, especially in the efficiency-focused code to avoid dynamic_casts. If there is a design that requires transformational action, try to develop alternative designs that do not require transformation;
If transformation is necessary, try to hide it behind a function. The client can then invoke the function without having to put the transformation in their own code;
Rather than using the traditional C + + style transformation, don't use legacy transformations. The former is very easy to identify, but also a comparative necromancy.
Avoid returning handles points to the inner component of the object
Avoid returning handles (including references, pointers, iterators) to the inside of the object. Adherence to this clause increases encapsulation, helps the const member function behave like a const, and minimizes the likelihood of a "virtual lift number card" occurring.
It's worth the effort to be "exceptionally safe."
The exception security function (Exception-safe functions) does not leak resources or allow any data structures to corrupt even if an exception occurs. Such function area is divided into three kinds of possible guarantees: basic type, strong type, not throw abnormal type;
"Strong assurance" can often be achieved by copy-and-swap, but "strong guarantee" is not for all functions can be achieved or have practical significance;
The "Exception security guarantee" provided by the function is usually the highest of the weakest in the exception security guarantee for each function that it invokes.
A thorough understanding of the inlining
Limit most inlining to small, frequently called functions. This makes future debugging and binary upgrades (binary upgradability) easier, as well as minimizing potential code bloat problems, maximizing the chances of a program's speed increase;
Do not declare them as inline just because the function templates appears in the header file.
Minimizes compilation dependencies between files
The general idea of supporting the minimization of compile dependencies is that it is dependent on the declarative, not on the definition. The two means based on this conception are handle classes and interface classes;
The library header file should be in the form of "complete and declarative Only" (Full and Declaration-only forms). This practice applies whether or not the templates is involved.
Make sure your public inherits the is-a relationship from the mold
"Public inheritance" means is-a. Every thing that applies to base classes must also apply to derived classes, because each derived class object is also a base class object.
Avoid shadowing inherited names
The name within the derived classes will obscure the name within the base classes. No one has ever wished to do so under public succession;
To let the masked name see the daylight, use a using declarative or a transfer function (forwarding functions).
Differentiate between interface inheritance and implementation inheritance
Interface inheritance differs from implementation inheritance. Under public inheritance, derived classes always inherits the interface of base class;
Pure virtual functions only specify interface inheritance;
Simple (non-pure) impure virtual function specifies interface inheritance and default implementation inheritance;
The Non-virtual function specifies interface inheritance and mandatory implementation inheritance.
Consider alternatives other than the virtual function
The alternative to the virtual function includes many forms of nvi manipulation and strategy design patterns. NVi technique itself is a special form of template method design mode;
One drawback of moving functions from member functions to class external functions is that non-member functions cannot access the non-public members of class;
The Tr1::function object behaves like a generic function pointer. Such an object can accept all the callable objects (callable entities) that are compatible with the given target signature (target signature).
Never redefine inherited non-virtual functions
Never redefine the inherited non-virtual function.
Never redefine inherited default parameter values
Never redefine an inherited default parameter value because the default parameter values are static bindings, and the virtual function-the only thing you should overwrite-is dynamic binding.
To Has-a or "appear according to something" by means of a composite mold.
The meaning of compound (composition) and public inheritance are completely different;
In an application domain (application domain), the compound means has-a (there is one). In implementing domains (Implementation domain), compounding means is-implemented-in-terms-of (implemented according to something).
Use private inheritance wisely and prudently
Private inheritance means is-implement-in-terms-of (implemented according to something). It is usually lower than the compound (composition) level. However, this design is reasonable when derived class needs to access the members of the protected base class, or to redefine the inherited virtual functions;
Unlike composite (composition), private inheritance can result in the optimization of empty base. This may be important to program developers who are committed to "minimizing the size of objects".
Use multiple inheritance wisely and prudently
Multiple inheritance is more complex than single inheritance. It may lead to new ambiguity, as well as the need for virtual inheritance;
Virtual inheritance increases the cost of size, speed, initialization (and assignment) complexity, and so on. If virtual base classes does not carry any data, it will be the most practical case;
Multiple inheritance does have a legitimate purpose. One of the episodes involves a two-phase combination of "public inheriting a interface class" and "private inheriting a class of assistance implementations."
Understanding implicit interfaces and compiler polymorphism
Classes and template both support interface (interfaces) and polymorphic (polymorphism);
For classes, the interface is displayed (explicit), centered on the function signature. Polymorphism is through the virtual function in the running period;
For the templates parameter, the interface is implicit (implicit), the foundation and the valid expression. The state is passed through template and function overloading parsing (function overloading resolution) occurs at compile time.
Understanding the dual meaning of TypeName
When declaring the template parameter, the Prefix keyword class and typename are interchangeable;
Use the Keyword typename to identify the nested subordinate type name, but not as the base class modifier in the base class lists (base column) or member initialization list (Member initial column).
Learn to handle names within a templated base class
The name of the member within the base class templates can be referred to in the derived class templates by "this->", or by a clearly written "base class qualifier modifier".
To extract the parameter-independent code from
Templates generates multiple classes and functions, so any template code should not have a dependency on a template parameter that causes bloat;
Code bloat due to non-type template parameters (Non-type templates parameters) can often be eliminated by replacing the template parameter with a function parameter or class member variable;
The code bloat due to type parameters is often reduced by allowing the representations type (instantiation types) with the exact same binary representation (binary) to share the implementation code.
Use member function templates to accept all compatible types
Use member function templates (member function template) to generate "acceptable all compatible types" functions;
If you declare member templates for the generalization copy construct or generalization assignment operation, you still need to declare the normal copy constructor and the copy assignment operator.
Define a non-member function for a template when a type conversion is required
When we write a class template that provides the "related to this template" function to support "Implicit type conversions for all parameters," define those functions as "friend functions inside the class template."
Please use traits classes expression type information
Traits classes makes "type-related information" available at compile time. They are accomplished by templates and "templates";
After the entire overloaded technology (overloading), traits classes is likely to perform if...else tests on the type at compile time.
Recognize template meta-programming
Templates metaprogramming (TMP, template metaprogramming) can move work from runtime to compile time, thus enabling early error detection and higher execution efficiency;
TMP can be used to generate custom code based on a combination of policy choices (based on combinations of pilicy choices) or to avoid generating code that is not appropriate for certain special types.