next up previous contents
Next: 4 Preparing the Code Up: c++_coding_guidelines Previous: 2 Guidelines for Names   Contents

Subsections

3 Recommendations for Usage of Language Features

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

3.2 Inline functions and assert(3)

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.

3.3 Constructors

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.

3.3.1 One argument constructors

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.

3.4 Destructors

3.4.1 Virtual Destructors

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.

3.5 Operators

3.5.1 assignment

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.

3.6 Books

Many of our ideas about C++ are based on the following books: 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 up previous contents
Next: 4 Preparing the Code Up: c++_coding_guidelines Previous: 2 Guidelines for Names   Contents
Jari Häkkinen 2016-06-13