
Update all links to C++ Core Guidelines to `e49158a`.
Refresh done using the following script and some manual edits:
db76e34e74/personal/fred-tingaud/rspec/refresh-cppcoreguidelines.py
When re-using this script, be mindful that:
- it does not cover `shared_content`
- it does not properly escape inline code in links (e.g., "[=]" or "`mutex`es")
- it does not change `C++` to `{cpp}` in link titles.
Co-authored-by: Marco Borgeaud <marco.borgeaud@sonarsource.com>
83 lines
3.3 KiB
Plaintext
83 lines
3.3 KiB
Plaintext
== Why is this an issue?
|
|
|
|
There are three ways to initialize a non-static data member in a class:
|
|
|
|
* With an in-class initializer
|
|
* In the initialization list of a constructor
|
|
* In the constructor body
|
|
|
|
You should use those methods in that order of preference. When applicable, in-class initializers are best, because they apply automatically to all constructors of the class (except for default copy/move constructors and constructors where an explicit initialization for this member is provided). But they can only be used for initialization with constant values.
|
|
|
|
|
|
If your member value depends on a parameter, you can initialize it in the constructor's initialization list. If the initialization is complex, you can define a function to compute the value, and use this function in the initializer list.
|
|
|
|
|
|
Initialization in the constructor body has several issues. First, it's not an initialization, but an assignment. Which means it will not work with all data types (const-qualified members, members of reference type, member of a type without default constructor...). And even if it works, the member will first be initialized, then assigned to, which means useless operations will take place. To prevent "use-before-set" errors, it's better to immediately initialize the member with its real value.
|
|
|
|
|
|
It's hard to find a good example where setting the value of a member in the constructor would be appropriate. One case might be when you assign to several data members in one operation. As a consequence constructor bodies are empty in many situations.
|
|
|
|
|
|
This rules raises an issue in two conditions:
|
|
|
|
* When you assign a value to a member variable in the body of a constructor.
|
|
* When you initialize a member variable in the initializer list of a constructor, but could have done so directly in the class:
|
|
** The initial value does not depend on a constructor parameter
|
|
** The variable has either no in-class initializer, or an in-class initializer with the same value as in the constructor
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,cpp]
|
|
----
|
|
class S {
|
|
int i1;
|
|
int i2;
|
|
int i3;
|
|
public:
|
|
S( int halfValue, int i2 = 0) : i2(i2), i3(42) { // Noncompliant for i1 and i3, compliant for i2
|
|
this->i1 = 2*halfValue;
|
|
}
|
|
};
|
|
----
|
|
|
|
|
|
=== Compliant solution
|
|
|
|
[source,cpp]
|
|
----
|
|
class S {
|
|
int i1;
|
|
int i2;
|
|
int i3 = 42; // In-class initializer
|
|
public:
|
|
S( int halfValue, int i2 = 0 ) : i1(2*halfValue), i2(i2) {} // Compliant
|
|
};
|
|
----
|
|
|
|
|
|
== Resources
|
|
|
|
* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#c48-prefer-in-class-initializers-to-member-initializers-in-constructors-for-constant-initializers[C.48: Prefer in-class initializers to member initializers in constructors for constant initializers]
|
|
* {cpp} Core Guidelines - https://github.com/isocpp/CppCoreGuidelines/blob/e49158a/CppCoreGuidelines.md#c49-prefer-initialization-to-assignment-in-constructors[C.49: Prefer initialization to assignment in constructors]
|
|
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
=== duplicates: S3230
|
|
|
|
=== on 2 Sep 2019, 22:15:24 Loïc Joly wrote:
|
|
\[~geoffray.adde]: Can you please review my changes?
|
|
|
|
=== on 23 Sep 2019, 11:20:25 Geoffray Adde wrote:
|
|
As discussed, all fine by me.
|
|
|
|
=== on 4 Oct 2019, 13:09:09 Geoffray Adde wrote:
|
|
moved to previously existing RSPEC-3230
|
|
|
|
endif::env-github,rspecator-view[]
|