Items
Prefer consts, enums and inlines to #defines.
For simple constants, prefer const objects or enums to #defines.
Such as code #define ASPECT_RAIO 1.653
, the symbolic name ASPECT_RATIO may never be seen by compilers. Thus when something wrong, the error message may refer to 1.653, not ASPECT_RATIO.
We prefer:
|
|
For function-like macros, prefer inline functions to #defines.
Macros have so many drawbacks, such as:
|
|
We prefer:
|
|
Use const whenever possible
Declaring something const helps compilers detect usage errors. const can be applied to objects at any scope, to function parameters and return types, and to member functions as a whole.
Compilers enforce bitwise constness, but you should program using logical constness.
The wonderful thing about const
is that is specify a semantic constraint-- a particular object should not be modified.
|
|
|
|
The reason that the result of operator* be a const object is we can avoid mistake if (a * b = c)
.
When const and non-const member functions have essentially identical implementations, code duplication can be avoided by having the non-const version cal the const version.
|
|
Make sure that objects are initialized before they're used.
Manually initialize objects of build-in type, because C++ only sometimes initializes them itself.
In a constructor, prefer use of the member initialization list to assignment inside the body of the constructor. List data members in the initialization list in the same order they're declared in the class.
Avoid initialization order problems across translation units by replacing non-local static objects with local static objects.
Know what functions c++ silently writes and calls
Compilers may implicitly generate a class's default constructor, copy constructor, copy assignment operator, and destructor.
Explicitly disallow the use of compiler-generated functions you do not want
To prevent these functions from being generated, you must declare them yourself.
|
|
Or create base class for inheriting:
|
|
To disallow functionality automatically provided by compilers, declare the corresponding member functions private and give no implementations. Using a base class like Uncopyable in one way to do this.
Declare destructors virtual in polymorphic base classes.
Polymorphic base classes should declare virtual destructors. If a class has any virtual functions, it should have a virtual destructor.
Classes not designed to be base classes or not designed to be used polymorphically should not declare virtual destructors.
Prevent exceptions from leaving destructors.
Destructors should never emit exceptions. If functions called in a destructor my throw, the destructor should catch any exceptions, then swallow them or terminate the program.
If class clients need to be able to react to exceptions thrown during an exception, the class should provide a regular function that performs the operation.
Never call virtual functions during construction or destruction
Don't call virtual functions during construction or destruction, because such calls will never go to a more derived class than that of the currently executing constructor or destructor.
Have assignment operators return a reference to *this
|
|
Have assignment operators return a reference to *this.
Handle assignment to self in operator=
|
|
While encounter self assignment, the follow code will be wrong
|
|
A good implementation can be follow:
|
|
|
|
The above implementation is self-assignment-safe and exception-safe;
Make sure operator= is well-behaved when an object is assigned to itself. Techniques include comparing addresses of source and target objects, careful statement ordering, and copy-and-swap.
Make sure that any function operating on more than one object behaves correctly if two or more of the objects are the same.
Copy all parts of an object.
Copying functions should be sure to copy all of an object's data members and all of its base class parts.
Don't try to implement one of the copying functions in terms of the other. Instead, put common functionality in a third function that both call.
Provide access to raw resources in resource-managing classes.
Access may be via explicit conversion or implicit conversion. In general, explicit conversion is safer, but implicit conversion is more convenient for clients.
Store newed objects in smart pointers in standalone statements.
We prefer
|
|
Not
|
|
In case, the priority() function throw exception cause memory leak.
Prefer pass-by-reference-to-const to pass-by-value.
prefer pass-by-reference-to-const over pass-by-value. It's typically more efficient and it avoid the slicing problem.
The rule doesn't apply to built-in types and STL iterator and function object types. For them, pass-by-value is usually appropriate.
Don't try to return a reference when you must return an object.
Wrong;
|
|
Prefer:
|
|
Never return a pointer or reference to a local stack object, a reference to a heap-allocated object, or a pointer or reference to a local static object if there is a chance that more than one such will be needed.
Declare data members private.
Declare data member private. It gives clients syntactically uniform access to data, affords fine-grained access control, allows invariants to be enforced, and offers class authors implementation flexibility.
protected is no more encapsulated than public.