Skip to content
Snippets Groups Projects
Commit b3b929c8 authored by Gururaj Shetty's avatar Gururaj Shetty
Browse files

Update C++ Coding Style Guide.rst

parent 86c9b8ee
No related branches found
No related tags found
No related merge requests found
...@@ -693,7 +693,7 @@ Preprocessor Directives ...@@ -693,7 +693,7 @@ Preprocessor Directives
======================= =======================
Rule 3.13.1 The number sign (#) that starts a preprocessor directive must be at the beginning of the line and can be indented in nested preprocessor directives. Rule 3.13.1 The number sign (#) that starts a preprocessor directive must be at the beginning of the line and can be indented in nested preprocessor directives.
--------------------------------------------------------------------------------------------------------------------------------------------------------------~~~~~ -------------------------------------------------------------------------------------------------------------------------------------------------------
The number sign (#) that starts a preprocessor directive must be at the The number sign (#) that starts a preprocessor directive must be at the
beginning of the line even through the preprocessor directive is inside beginning of the line even through the preprocessor directive is inside
...@@ -1795,8 +1795,7 @@ Rule 7.1.3 If copy/move constructors and copy/move assignment operators are not ...@@ -1795,8 +1795,7 @@ Rule 7.1.3 If copy/move constructors and copy/move assignment operators are not
Note: If users do not define it, the compiler will generate copy constructors and copy assignment operators, move constructors and move assignment operators (move semantic functions will be available in versions later than C++ 11). If we do not use copy constructors or copy Note: If users do not define it, the compiler will generate copy constructors and copy assignment operators, move constructors and move assignment operators (move semantic functions will be available in versions later than C++ 11). If we do not use copy constructors or copy
assignment operators, explicitly delete them. assignment operators, explicitly delete them.
#. Set copy constructors or copy assignment operators to private and do Set copy constructors or copy assignment operators to private and do not implement them.
not implement them.
.. code:: cpp .. code:: cpp
...@@ -1806,13 +1805,12 @@ assignment operators, explicitly delete them. ...@@ -1806,13 +1805,12 @@ assignment operators, explicitly delete them.
Foo& operator=(const Foo&); Foo& operator=(const Foo&);
}; };
#. Use delete provided by C++ 11. For details, see Rule 10.1.3 in chapter 10 Modern C++ Features. Use delete provided by C++ 11. For details, see Rule 10.1.3 in chapter 10 Modern C++ Features.
Rule 7.1.4 Copy constructors and copy assignment operators should be implemented or forbidden together. Rule 7.1.4 Copy constructors and copy assignment operators should be implemented or forbidden together.
------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------
Both copy constructors and copy assignment operators provide copy Both copy constructors and copy assignment operators provide copy semantics. They should be implemented or hidden together.
semantics. They should be implemented or hidden together.
.. code:: cpp .. code:: cpp
...@@ -2578,28 +2576,22 @@ Rule 9.3.1 If type casting is required, use the type casting provided by the C++ ...@@ -2578,28 +2576,22 @@ Rule 9.3.1 If type casting is required, use the type casting provided by the C++
**Note**: **Note**:
The type casting provided by C++ is more targeted, easy to read, and The type casting provided by C++ is more targeted, easy to read, and more secure than the C style. C++ provides the following types of
more secure than the C style. C++ provides the following types of casting:
casting: - Type casting: 1. ``dynamic_cast``: Used to inherit the * Type casting:
downstream transformation of the system. ``dynamic_cast`` has the type * ``dynamic_cast``: Used to inherit the downstream transformation of the system. ``dynamic_cast`` has the type
check function. Design the base class and derived class to avoid using check function. Design the base class and derived class to avoid using dynamic_cast for casting.
dynamic_cast for casting. 2. ``static_cast``: Similar to the C style * ``static_cast``: Similar to the C style casting, which can be used to convert a value, or to convert the pointer or reference of a derived class
casting, which can be used to convert a value, or to convert the pointer into a base class pointer or reference.
or reference of a derived class into a base class pointer or reference. This casting is often used to eliminate type ambiguity brought on by multiple inheritance, which is relatively safe. If it is a pure arithmetic
This casting is often used to eliminate type ambiguity brought on by conversion, use the braces as stated in the following text.
multiple inheritance, which is relatively safe. If it is a pure * ``reinterpret_cast``: Used to convert irrelevant types. ``reinterpret_cast`` forces the compiler to reinterpret the memory of a
arithmetic conversion, use the braces as stated in the following text. certain type of objects into another type, which is an unsafe conversion. It is recommended that ``reinterpret_cast`` be used as little as possible.
3. ``reinterpret_cast``: Used to convert irrelevant types. * ``const_cast``: Used to remove the ``const`` attribute of an object so that the object can be modified. You are advised to use ``const_cast`` as
``reinterpret_cast`` forces the compiler to reinterpret the memory of a little as possible.
certain type of objects into another type, which is an unsafe
conversion. It is recommended that ``reinterpret_cast`` be used as * Arithmetic conversion: (Supported by C++ 11 and later versions) If the type information is not lost, for example, the casting from float to double,
little as possible. 4. ``const_cast``: Used to remove the ``const`` or from int32 to int64, the braces syntax is recommended.
attribute of an object so that the object can be modified. You are
advised to use ``const_cast`` as little as possible.
- Arithmetic conversion: (Supported by C++ 11 and later versions) If
the type information is not lost, for example, the casting from float
to double, or from int32 to int64, the braces syntax is recommended.
.. code:: cpp .. code:: cpp
...@@ -2609,14 +2601,10 @@ advised to use ``const_cast`` as little as possible. ...@@ -2609,14 +2601,10 @@ advised to use ``const_cast`` as little as possible.
Recommendation 9.3.1 Avoid using ``dynamic_cast``. Recommendation 9.3.1 Avoid using ``dynamic_cast``.
-------------------------------------------------- --------------------------------------------------
1. ``dynamic_cast`` depends on the RTTI of C++ so that the programmer * ``dynamic_cast`` depends on the RTTI of C++ so that the programmer can identify the type of the object in C++ at run time.
can identify the type of the object in C++ at run time. * ``dynamic_cast`` indicates that a problem has occurred in the design of the base class and derived class.The derived class destroys the
2. ``dynamic_cast`` indicates that a problem has occurred in the design contract of the base class and it is necessary to use ``dynamic_cast`` to convert the class to a subclass for special processing. In this case, it
of the base class and derived class.The derived class destroys the is more desirable to improve the design of the class, instead of using ``dynamic_cast`` to solve the problem.
contract of the base class and it is necessary to use
``dynamic_cast`` to convert the class to a subclass for special
processing. In this case, it is more desirable to improve the design
of the class, instead of using ``dynamic_cast`` to solve the problem.
Recommendation 9.3.2 Avoid using ``reinterpret_cast``. Recommendation 9.3.2 Avoid using ``reinterpret_cast``.
------------------------------------------------------ ------------------------------------------------------
...@@ -2806,12 +2794,10 @@ string object is not modified within the lifecycle of the saved pointer. ...@@ -2806,12 +2794,10 @@ string object is not modified within the lifecycle of the saved pointer.
Recommendation 9.5.1 Use std::string instead of char*. Recommendation 9.5.1 Use std::string instead of char*.
------------------------------------------------------ ------------------------------------------------------
Note: Using string instead of ``char*`` has the following advantages: 1. Note: Using string instead of ``char*`` has the following advantages:
There is no need to consider the null character ’\0’at the end. 2. You * There is no need to consider the null character ’\0’at the end.
can directly use operators such as ``+``, ``=``, and ``==``, and other * You can directly use operators such as ``+``, ``=``, and ``==``, and other character and string operation functions.
character and string operation functions. 3. There is no need to * There is no need to consider memory allocation operations.This helps avoid explicit usage of ``new`` and ``delete`` and the resulting errors.
consider memory allocation operations.This helps avoid explicit usage of
``new`` and ``delete`` and the resulting errors.
Note that in some STL implementations, string is based on the Note that in some STL implementations, string is based on the
copy-on-write policy, which causes two problems. One is that the copy-on-write policy, which causes two problems. One is that the
...@@ -2948,20 +2934,12 @@ Exceptions ...@@ -2948,20 +2934,12 @@ Exceptions
Recommendation 9.7.1 If the function does not throw an exception, the declaration is ``noexcept``. Recommendation 9.7.1 If the function does not throw an exception, the declaration is ``noexcept``.
-------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------
**Reasons:** 1. If the function does not throw an exception, the **Reasons:**
declaration is ``noexcept``, which enables the compiler to optimize the * If the function does not throw an exception, the declaration is ``noexcept``, which enables the compiler to optimize thefunction to the maximum extent, for example, reducing the execution paths and improving the efficiency of exiting when an error occurs.
function to the maximum extent, for example, reducing the execution * For STL containers such as ``vector``, to ensure the interface robustness, if the ``move`` constructor of saved items is not declared as ``noexcept``, the ``copy machanism`` instead of the ``move machanism`` is used when the items are removed from the container. This would cause
paths and improving the efficiency of exiting when an error occurs. 2. performance loss risks. If the function does not throw an exception, or a program does not intercept and process an
For STL containers such as ``vector``, to ensure the interface exception thrown by the function, new ``noexcept`` keywords can be used to modify the function, indicating that the function does not throw an
robustness, if the ``move`` constructor of saved items is not declared exception or the thrown exception is not intercepted or processed. For example:
as ``noexcept``, the ``copy machanism`` instead of the
``move machanism`` is used when the items are removed from the
container. This would cause performance loss risks. If the function does
not throw an exception, or a program does not intercept and process an
exception thrown by the function, new ``noexcept`` keywords can be used
to modify the function, indicating that the function does not throw an
exception or the thrown exception is not intercepted or processed. For
example:
.. code:: cpp .. code:: cpp
...@@ -3028,9 +3006,9 @@ The disadvantages of template proramming are as follows: ...@@ -3028,9 +3006,9 @@ The disadvantages of template proramming are as follows:
the transformation makes sense in all of them. the transformation makes sense in all of them.
Therefore, it is recommended that \_\_ template programming be used only Therefore, it is recommended that \_\_ template programming be used only
in a small number of basic components and basic data structure__. When in a small number of basic components and basic data structure. When
using the template programming, minimize the **complexity as much as using the template programming, minimize the **complexity as much as
possible, and** avoid exposing the template__. It is better to hide possible, and** avoid exposing the template. It is better to hide
programming as an implementation detail whenever possible, so that programming as an implementation detail whenever possible, so that
user-facing headers are readable. And you should write sufficiently user-facing headers are readable. And you should write sufficiently
detailed comments for code that uses templates. detailed comments for code that uses templates.
...@@ -3162,12 +3140,10 @@ modify the overridden function when there are multiple subclasses. ...@@ -3162,12 +3140,10 @@ modify the overridden function when there are multiple subclasses.
void Bar() override; // Compilation failed: base::Bar is not a virtual function. void Bar() override; // Compilation failed: base::Bar is not a virtual function.
}; };
**Summary** 1. When defining the virtual function for the first time **Summary**
based on the base class, use the keyword ``virtual``. 2. When overriding #. When defining the virtual function for the first time based on the base class, use the keyword ``virtual``.
the virtual function by a subclass in a base class, including #. When overriding the virtual function by a subclass in a base class, including destructors, use the keyword ``override`` or ``final`` instead of ``virtual``.
destructors, use the keyword ``override`` or ``final`` instead of #. For the non-virtual function, do not use ``virtual`` or ``override``.
``virtual``. 3. For the non-virtual function, do not use ``virtual`` or
``override``.
Rule: 10.1.2 Use the keyword ``delete`` to delete functions. Rule: 10.1.2 Use the keyword ``delete`` to delete functions.
------------------------------------------------------------ ------------------------------------------------------------
...@@ -3389,18 +3365,18 @@ performance and compatibility. ...@@ -3389,18 +3365,18 @@ performance and compatibility.
Rule 10.2.2 Use ``unique_ptr`` instead of ``shared_ptr``. Rule 10.2.2 Use ``unique_ptr`` instead of ``shared_ptr``.
--------------------------------------------------------- ---------------------------------------------------------
**Reasons:** 1. Using ``shared_ptr`` a lot has an overhead (atomic **Reasons:**
operations on the ``shared_ptr``\ s reference count have a measurable #. Using ``shared_ptr`` a lot has an overhead (atomic operations on the ``shared_ptr``\ s reference count have a measurable
cost). 2. Shared ownership in some cases (such as circular dependency) cost).
may create objects that can never be released. 3. Shared ownership can #.Shared ownership in some cases (such as circular dependency) may create objects that can never be released.
be an attractive alternative to careful ownership design but it may #.Shared ownership can be an attractive alternative to careful ownership design but it may obfuscate the design of a system.
obfuscate the design of a system.
Rule 10.2.3 Use ``std::make_unique`` instead of ``new`` to create a ``unique_ptr``. Rule 10.2.3 Use ``std::make_unique`` instead of ``new`` to create a ``unique_ptr``.
----------------------------------------------------------------------------------- -----------------------------------------------------------------------------------
**Reasons:** 1. ``make_unique`` provides a simpler creation method. 2. **Reasons:**
``make_unique`` ensures the exception safety of complex expressions. #. ``make_unique`` provides a simpler creation method.
#. ``make_unique`` ensures the exception safety of complex expressions.
**Example:** **Example:**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment