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
=======================
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
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
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.
#. Set copy constructors or copy assignment operators to private and do
not implement them.
Set copy constructors or copy assignment operators to private and do not implement them.
.. code:: cpp
......@@ -1806,13 +1805,12 @@ assignment operators, explicitly delete them.
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.
-------------------------------------------------------------------------------------------------------
Both copy constructors and copy assignment operators provide copy
semantics. They should be implemented or hidden together.
Both copy constructors and copy assignment operators provide copy semantics. They should be implemented or hidden together.
.. code:: cpp
......@@ -2578,28 +2576,22 @@ Rule 9.3.1 If type casting is required, use the type casting provided by the C++
**Note**:
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
casting: - Type casting: 1. ``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
dynamic_cast for casting. 2. ``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 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 conversion, use the braces as stated in the following text.
3. ``reinterpret_cast``: Used to convert irrelevant types.
``reinterpret_cast`` forces the compiler to reinterpret the memory of a
certain type of objects into another type, which is an unsafe
conversion. It is recommended that ``reinterpret_cast`` be used as
little as possible. 4. ``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 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.
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
casting:
* Type casting:
* ``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 dynamic_cast for casting.
* ``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
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
conversion, use the braces as stated in the following text.
* ``reinterpret_cast``: Used to convert irrelevant types. ``reinterpret_cast`` forces the compiler to reinterpret the memory of a
certain type of objects into another type, which is an unsafe conversion. It is recommended that ``reinterpret_cast`` be used as little as possible.
* ``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
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
......@@ -2609,14 +2601,10 @@ advised to use ``const_cast`` as little as possible.
Recommendation 9.3.1 Avoid using ``dynamic_cast``.
--------------------------------------------------
1. ``dynamic_cast`` depends on the RTTI of C++ so that the programmer
can identify the type of the object in C++ at run time.
2. ``dynamic_cast`` indicates that a problem has occurred in the design
of the base class and derived class.The derived class destroys the
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.
* ``dynamic_cast`` depends on the RTTI of C++ so that the programmer 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
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``.
------------------------------------------------------
......@@ -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*.
------------------------------------------------------
Note: Using string instead of ``char*`` has the following advantages: 1.
There is no need to consider the null character ’\0’at the end. 2. You
can directly use operators such as ``+``, ``=``, and ``==``, and other
character and string operation functions. 3. There is no need to
consider memory allocation operations.This helps avoid explicit usage of
``new`` and ``delete`` and the resulting errors.
Note: Using string instead of ``char*`` has the following advantages:
* There is no need to consider the null character ’\0’at the end.
* You can directly use operators such as ``+``, ``=``, and ``==``, and other character and string operation functions.
* There is no need to 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
copy-on-write policy, which causes two problems. One is that the
......@@ -2948,20 +2934,12 @@ Exceptions
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
declaration is ``noexcept``, which enables the compiler to optimize the
function to the maximum extent, for example, reducing the execution
paths and improving the efficiency of exiting when an error occurs. 2.
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 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:
**Reasons:**
* 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.
* 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
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
......@@ -3028,9 +3006,9 @@ The disadvantages of template proramming are as follows:
the transformation makes sense in all of them.
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
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
user-facing headers are readable. And you should write sufficiently
detailed comments for code that uses templates.
......@@ -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.
};
**Summary** 1. When defining the virtual function for the first time
based on the base class, use the keyword ``virtual``. 2. When overriding
the virtual function by a subclass in a base class, including
destructors, use the keyword ``override`` or ``final`` instead of
``virtual``. 3. For the non-virtual function, do not use ``virtual`` or
``override``.
**Summary**
#. When defining the virtual function for the first time based on the base class, use the keyword ``virtual``.
#. When overriding the virtual function by a subclass in a base class, including destructors, use the keyword ``override`` or ``final`` instead of ``virtual``.
#. For the non-virtual function, do not use ``virtual`` or ``override``.
Rule: 10.1.2 Use the keyword ``delete`` to delete functions.
------------------------------------------------------------
......@@ -3389,18 +3365,18 @@ performance and compatibility.
Rule 10.2.2 Use ``unique_ptr`` instead of ``shared_ptr``.
---------------------------------------------------------
**Reasons:** 1. 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)
may create objects that can never be released. 3. Shared ownership can
be an attractive alternative to careful ownership design but it may
obfuscate the design of a system.
**Reasons:**
#. Using ``shared_ptr`` a lot has an overhead (atomic operations on the ``shared_ptr``\ s reference count have a measurable
cost).
#.Shared ownership in some cases (such as circular dependency) may create objects that can never be released.
#.Shared ownership can be an attractive alternative to careful ownership design but it may obfuscate the design of a system.
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.
``make_unique`` ensures the exception safety of complex expressions.
**Reasons:**
#. ``make_unique`` provides a simpler creation method.
#. ``make_unique`` ensures the exception safety of complex expressions.
**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