Next: 4 Preparing the Code
Up: c++_coding_guidelines
Previous: 2 Guidelines for Names
Contents
Subsections
In this section we leave the guidelines for facilitating
communication. Instead we will focus on practices of a particular
programming style. This programming style is based on Jaris and
Markus collective experience. We believe that adhering to this
programming style has a positive aspect on the quality of our
code. This is not intendend to be a legislation of any kind, and we do
not want it to limit our developers. We present this in hope that it
will inspire others or at least start discussions. Minimally, it will
at least make it easier to understand our code.
3.1 Namespaces
We use namespaces, and avoid importing all symbols from namespaces we
use in our programs. Thus, the use of a file wide using
namespace std; is deprecated and strictly forbidden in header
files. Putting the statement using namespace std; into a
header file will pollute the namespace for everyone using the header
file.
In the rare occasions you must import all symbols from a namespace do
it within a local scope as in
int main(const int argc,const char* argv[])
{
using namespace::std; // import all std symbols!
cout << "This operator usage works fine here\n";
}
since this will only polute the main scope. Explicit import
of classes is preferred, e.g. use using
theplu::my_project::MyClass; to import MyClass. Similarily,
if you are only using cout, use the explicit import
using std::cout; instead of importing the entire std
namespace.
When we create our own namespaces we do it in a nested fashion. All
packages developed in-house should be in theplu (lower case
characters) namespace, and a specific package is then defined within
the theplu namespace,
namespace theplu {
namepace my_project {
class MyClass
{
};
}} // of namepace my_project and namespace theplu
Inline functions should be used sparingly and only for one line
statements. In principle inlining should only be used when a
performance increase can be proved.
The assert macro must never be used in header files (i.e., in inline
functions) to avoid different debug level in header files and
production program libraries, and to avoid changes in library
behaviour with -NDEBUG usage.
We prefer all our classes to have a copy constructor and we like their
implementation to use the assignment operator. This is beacuse
eventually one will almost always want to copy an object and then it
should be done properly. If no copy constructor is implemented we
recommend to declare it private, this will create a compiler
diagnostic if the constructor is implicitly used.
Implementing the copy constructor in terms of the assignment operator
removes duplication of code. Remember that sometimes data members of
the object to be constructed has to be properly initialized before the
call to the assignment operator.
One argument constructors can be used in implicit conversions, which
can lead to unexpected behaviour. Therefore, we declare our one
argument constructors explicit, if we do not specifically want
them to work in implicit conversions.
We always make our destructors virtual, unless we are certain that no
class will ever be derived from them. This is due to that if one tries
to delete a derived class through a base class pointer and the base
class lacks a virtual destructor the results are undefined.
We prefer all our classes to have an assignment operator. Assignment
operators should return a reference to this, check (avoid) for
assignment to self, and make sure that all data members are properly
assigned. Also, remember to free allocated resources correctly in
assignment operators. If no assignment operator is implemented declare
it private in order to avoid implicit usage.
Many of our ideas about C++ are based on the following books:
- Design Patterns [3]
- Effective C++ [4]
- More Effective C++ [5]
- Effective STL [6]
Use these books as references. Each book contains a list of the
items/patterns they contain. Familiarize yourself with these lists and
look at them every time you think about the design of something. Most
likely they describe the problem you are considering.
Next: 4 Preparing the Code
Up: c++_coding_guidelines
Previous: 2 Guidelines for Names
Contents
Jari Häkkinen
2016-06-13