Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
roth_stephan_clean_c20_sustainable_software_development_patt.pdf
Скачиваний:
29
Добавлен:
27.03.2023
Размер:
7.26 Mб
Скачать

Chapter 4 Basics of Clean C++

The Power of const Correctness

const correctness is a powerful approach to better and safer code in C++. The use of const can save a lot of trouble and debugging time, because violations of const cause compile-time errors. And as a kind of side effect, the use of const can also support the compiler in applying some of its optimization algorithms. That means that the

proper use of this qualifier is also an easy way to raise the execution performance of the program a little bit.

Unfortunately, many developers don’t appreciate the benefits of an intense use of const.

Tip  Pay attention to const correctness. Use const as much as possible, and always choose a proper declaration of variables or objects as mutable or immutable.

In general, the const keyword in C++ prevents objects from being mutated by the program. But const can be used in different contexts. This keyword has many faces.

Its simplest use is to define a variable as a constant:

const long double PI = 3.141592653589794;

MATHEMATICAL CONSTANTS [C++20]

Since C++20, the C++ numerics library has been extended, among others by a number of mathematical constants, which are defined in the <numbers> header. Here is a small selection:

#include <numbers>

 

auto pi = std::numbers::pi;

// the Archimedes constant aka PI:

 

3.141592653589794

auto e = std::numbers::e;

// Euler's number: 2.718281828459045

auto phi = std::numbers::phi;

// the golden ratio Φ constant:

 

1.618033988749895

The C-style defined mathematical constants in the <cmath> header, which had to be made accessible by defining _USE_MATH_DEFINES before including the header, are thus obsolete.

112

Chapter 4 Basics of Clean C++

Another use of const is to prevent parameters that are passed into a function from being mutated. Since there are several variations, it often leads to confusion. Here are some examples:

unsigned

int

determineWeightOfCar(Car const* car);

// 1

void lacquerCar(Car* const car);

// 2

unsigned

int

determineWeightOfCar(Car const* const car);

// 3

void

printMessage(const std::string& message);

//

4

void

printMessage(std::string const& message);

//

5

•\

The pointer car points to a constant object of type Car, that is, the

 

Car object (the “pointee”) cannot be modified.

•\

The pointer car is a constant pointer of type Car, that is, you can

 

modify the Car object, but you cannot modify the pointer (e.g., assign

 

a new instance of Car to it).

•\

In this case, both the pointer and the pointee (the Car object) cannot

 

be modified.

•\

The argument message is passed by reference-to-const to the

 

function, that is, the string variable being referenced is not allowed to

 

be changed inside the function.

•\

This is just an alternative notation for a const reference argument. It

 

is functionally equivalent to line 4 (...which I prefer, by the way).

Tip  There is a simple rule of thumb to read const qualifiers in the right manner. If you read them from right to left, then any appearing const qualifier modifies the thing to the left of it. Exception: If there is nothing on the left, for example, at the beginning of a declaration, then const modifies the thing to its right.

Another use of the const keyword is to declare a (non-static) member-function of a class as const, like in this example on line 5:

01 #include <string>

02

03 class Car {

113