Effective C + + 55 terms

Source: Internet
Author: User

Effective C + + 55 clauses make yourself accustomed to C + +
    • Depending on C + + as a language federation

      The code for efficient programming of C + + varies depending on what part of C + + you use.

    • Try to replace # define with Const,enums,inline

      For simple constants, it is better to replace #defines with const objects or enums;

      For macros that resemble functions (macros), it is best to replace #defines with the inline function instead.

    • Use const whenever possible

      Declaring something as const can help the compiler detect the error usage. Const can be applied to objects in any scope, function parameters, function return types, member function ontology;

      The compiler enforces bitwise constness, and you should use "Conceptual constants" (conceptual constness) when you write your program.

      When the const and NON-CONST member functions have a substantially equivalent implementation, making the NON-CONST version call the const version avoids code duplication.

    • Determines that an object has been initialized before it is used

      Manual initialization of built-in objects, because C + + does not guarantee initialization of them;

      Constructors are best used with member initial values (member initialization list) instead of using assignment operations (Assignment) within the constructor body. The initial Value column lists the member variables in the same order as they are declared in class;

      To exempt the "cross-compilation unit value Initialization order" issue, it is easy to replace the Non-local static object with the local static object.

Construction/destructor/assignment operations
  • 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.

Resource Management
    • Managing Resources with objects

      To prevent resource leaks, use the Raii object, which obtains resources in the constructor and frees resources in destructors;

      The two commonly used RAII classes are tr1::shared_ptr and auto_ptr respectively. The former is usually a better choice, because its copy behavior is more intuitive. If you select Auto_ptr, the copy action will cause it (copied) to point to null.

    • Beware of copying behavior in resource management classes

      Copying a Raii object must replicate the resources it manages, so the copying behavior of the resource determines the copying behavior of the Raii object;

      The general and common RAII class copying behavior is: Suppress the copying, implement the introduction counting method (reference counting). But other behaviors can also be achieved.

    • Provide access to the original resource in the resource management class

      APIs often require access to raw resources, so each RAII class should provide a way to "get the resources it manages";

      Access to the original resource may be transformed by a display or by an implicit conversion. Generally speaking, conversion is more secure, but implicit conversion is more convenient for customers.

    • Use new and delete in pairs to take the same form

      If you use [] in a new expression, you must also use [] in the corresponding delete expression. If you do not use [] in the new expression, you must not use [] in the corresponding delete expression.

    • Placing a newed object into a smart pointer with a standalone statement

      Stores the Newed object in the (placed) smart pointer in a stand-alone statement. If you do not, once an exception is thrown, it is possible to cause an imperceptible resource leak.

Design and declaration
  • 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.

Realize
  • 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.

Inheritance and object-oriented design
  • 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."

Templates and generics programming
  • 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.

customizing New and delete
    • Understand the behavior of New-handler

      Set_new_handler allows the client to specify a function that is called when the memory allocation is not met;

      Nothrow New is a fairly limited tool because it only applies to memory allocations, and subsequent constructor calls may throw exceptions.

    • Understand the appropriate replacement time for new and delete

      There are many reasons to write a custom new and delete, including improving performance, debugging heap errors, and collecting heap usage information.

    • You need to stick to the routine when writing new and delete

      Operator new should contain an infinite loop in which to attempt to allocate memory, and if it does not meet the memory requirements, call New-handler. It should also be able to handle 0 bytes applications. The class-specific version should also handle "larger (error) applications than the correct size";

      operator delete should not do anything when a null pointer is received. The class-specific version should also handle "larger (error) applications than the correct size."

    • Wrote placement new also to write placement delete

      When you write a placement operator new, make sure it also writes out the corresponding placement operator delete. If you do not do so, your program may occur with a hidden micro-time memory leak;

      When declaring placement new and placement Delete, make sure that you do not inadvertently (unintentionally) obscure their normal version.

Miscellaneous discussions
    • Do not warn the compiler

      Take the compiler's warning message seriously. Strive to honor the "no warning" at the highest (most demanding) warning level of your compiler;

      Do not rely too much on the compiler's alarm function, because different compilers do not have the same attitude towards things. Once ported to another compiler, the warning message you relied on might disappear.

    • Familiarize yourself with standard libraries, including TR1

      The main functions of C + + standard library consist of STL, IOStreams and locales. and contains C99 standard program library;

      TR1 adds support for pointers only (such as tr1::shared_ptr), generalized function pointers (tr1::function), hash-based containers, regular expressions (regular expression), and 10 additional components;

      TR1 itself is only a specification. In order to obtain the benefits offered by TR1, a physical one is needed. A good source of physical resources is boost.

    • Make yourself familiar with boost

      Boost is a community and a website. Dedicated to free, open source, peer review of C + + library development. Boost plays an influential role in the C + + standardization process;

      Boost offers many TR1 component implementations, as well as many other library applications.

References: Effective C + + 55 terms

Effective C + + 55 terms

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.