====== Coding Style ======
===== Spaces vs Tabs =====
Qt Creator uses spaces for indentation. Since we will probably be using Qt and since Qt Creator is the default IDE when writing code using Qt, **spaces** should be used for indentation.
===== Braces =====
Opening and closing braces should be on a new line, in most cases: classes, functions, namespaces, arrays, etc. The only exception would be initialization.
namespace MyNamespace
{
void MyFunction()
{
while(true)
{
int value{42};
}
}
}
===== Naming =====
^ Item ^ Example ^ Comment ^
| type (class/struct) | SomeExample | |
| variable | someExample | |
| member variable | m_someExample | |
| global variables | gSomeExample | should be avoided |
| function | someExample() | function names should begin with a verb: computeMap(), displayWindow() |
| member function | someExample() | |
| getter function | name() | not getName(), Qt convention |
| setter function | setName() | |
| namespace | SomeExample | |
| template parameter | SomeExample | |
**Never use abbreviations in names, having long names is not an issue: all IDEs have an auto-completion feature.**
// Bad
void getNbApples()
{
int avgFuncSizePerAlloc = 42;
//...
}
// Good
void getAppleCount()
{
int averageFunctionSizePerAllocation = 42;
//...
}
**Prefer using meaningful names instead of "one letter" names like i,j,k.**
// Bad
for(int i = 0; i < ducks.size(); ++i)
{
//...
}
// Good
for(int duckIndex = 0; duckIndex < ducks.size(); ++duckIndex)
{
//...
}
**Variables representing GUI elements should be suffixed by their type**
// Bad
QPushButton *exitApplication;
QLabel *duckCount;
// Good
QPushButton *exitApplicationPushButton;
QLabel *duckCountLabel;
===== Code files =====
==== Code separation ====
Generally speaking, each class/struct should have its declaration in one file (header) and its definition in another file (source file). If a class/struct is very small then it can be contained in a header, for example if it only contains variables and no functions. Qt specific: note that QObject/QWidget-based classes have to have their own header file in order to the [[http://doc.qt.io/qt-5/moc.html|moc]] (Qt's Meta-Object Compiler) to find them.
==== Naming ====
Source files should have the .cpp extension (common practice) and header files the .hpp extension. Note here that the .h extension may be more common, but I personally think that the .hpp extension makes more sense since C++ headers are not generally compatible with the C language.
==== Header guards ====
Header guards are a C++-specific feature kept for historical reasons. The official way of using them is to put all the header code between #defines:
#ifndef MY_HEADER_FILE_H
#define MY_HEADER_FILE_H
//...
#endif // MY_HEADER_FILE_H
**However**, in practice I find this to be dangerous and I have encountered some particularly serious bugs using this method. Indeed, if you happen to copy/paste a header file you will need to remember having to change the header guard #define name. If you do not do this and if you include both header files, **only the first one will be effectively included**.
Another way to shoot yourself in the foot using header guards is the use of a namespace. Since preprocessor instructions cannot use them you will get into trouble if a header file within a namespace has the same name as another header file outside of it.
For these reasons, I recommend instead the use of the non-standard feature called "pragma once":
#pragma once
//...
This feature in implemented in all known compilers and is both easier to use and foolproof. It has not been accepted into the C++ standard because of some particular cases, like having source files on multiple "remote mounts": https://stackoverflow.com/questions/23696115/is-pragma-once-part-of-the-c11-standard.