You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I added a few missing punctuations and cleaned up the wording in a few places to
make it a little clearer.
I fixed the name of the constructor in a couple of the code examples.
Copy file name to clipboardExpand all lines: 03-Style.md
+46-45Lines changed: 46 additions & 45 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
1
# Style
2
2
3
-
Consistency of style is more important. Second most importance is following a style that the average C++ programmer is used to reading.
3
+
Consistency is the most important aspect of style. The second most important aspect is following a style that the average C++ programmer is used to reading.
4
4
5
-
C++ allows for arbitrary-length identifier names, so there's no reason to be terse when naming variables. Use descriptive names, and be consistent in the style.
5
+
C++ allows for arbitrary-length identifier names, so there's no reason to be terse when naming things. Use descriptive names, and be consistent in the style.
6
6
7
7
*`CamelCase`
8
8
*`snake_case`
@@ -11,27 +11,27 @@ are common examples. *snake_case* has the advantage that it can also work with s
11
11
12
12
## Common C++ Naming Conventions
13
13
14
-
* Types start with capitals: `MyClass`
15
-
*functions and variables start with lower case: `myMethod`
16
-
*constants are all capital: `const double PI=3.14159265358979323;`
14
+
* Types start with upper case: `MyClass`.
15
+
*Functions and variables start with lower case: `myMethod`.
16
+
*Constants are all upper case: `const double PI=3.14159265358979323;`.
17
17
18
18
C++ Standard Library (and other well-known C++ libraries like [Boost](http://www.boost.org/)) use these guidelines:
19
19
20
-
* Macro names use uppercase with underscores: `INT_MAX`
21
-
* Template parameter names use camel case: `InputIterator`
22
-
* All other names use snake case: `unordered_map`
20
+
* Macro names use upper case with underscores: `INT_MAX`.
21
+
* Template parameter names use camel case: `InputIterator`.
22
+
* All other names use snake case: `unordered_map`.
23
23
24
24
## Distinguish Private Object Data
25
25
26
-
Name private data with a `m_` prefix to distinguish it from public data. `m_` stands for "member" data
26
+
Name private data with a `m_` prefix to distinguish it from public data. `m_` stands for "member" data.
27
27
28
28
## Distinguish Function Parameters
29
29
30
-
The most important thing is consistency within your codebase, this is one possibility to help with consistency.
30
+
The most important thing is consistency within your codebase; this is one possibility to help with consistency.
31
31
32
32
Name function parameters with an `t_` prefix. `t_` can be thought of as "the", but the meaning is arbitrary. The point is to distinguish function parameters from other variables in scope while giving us a consistent naming strategy.
33
33
34
-
By using `t_` for parameters and `m_` for module data, we can have consistency with both public members of structs and private members of classes.
34
+
By using `t_` for parameters and `m_` for member data, we can have consistency with both public members of structs and private members of classes.
35
35
36
36
Any prefix or postfix can be chosen for your organization. This is just one example. *This suggestion is controversial, for a discussion about it see issue [#11](https://github.com/lefticus/cppbestpractices/issues/11).*
37
37
@@ -41,17 +41,17 @@ struct Size
41
41
int width;
42
42
int height;
43
43
44
-
ValueType(int t_width, int t_height) : width(t_width), height(t_height) {}
44
+
Size(int t_width, int t_height) : width(t_width), height(t_height) {}
45
45
};
46
46
47
-
// this version might make sense for thread safety or something,
48
-
// but more to the point, sometimes we need to hide data, sometimes we don't
47
+
// This version might make sense for thread safety or something,
48
+
// but more to the point, sometimes we need to hide data, sometimes we don't.
49
49
class PrivateSize
50
50
{
51
51
public:
52
52
int width() const { return m_width; }
53
53
int height() const { return m_height; }
54
-
ValueType(int t_width, int t_height) : m_width(t_width), m_height(t_height) {}
54
+
PrivateSize(int t_width, int t_height) : m_width(t_width), m_height(t_height) {}
55
55
56
56
private:
57
57
int m_width;
@@ -64,7 +64,7 @@ class PrivateSize
64
64
65
65
## Don't Name Anything Starting With `_`
66
66
67
-
If you do, you risk broaching on names reserved for implementation use:
67
+
If you do, you risk colliding with names reserved for compiler and standard library implementation use:
Make sure generated files go into build folder, not the source folder
97
+
Make sure generated files go into an output folder that is separate from the source folder.
98
98
99
99
100
100
## Use `nullptr`
101
101
102
-
C++11 introduces `nullptr` which is a special type denoting a null pointer value. This should be used instead of `0` or `NULL` to indicate a null pointer.
102
+
C++11 introduces `nullptr` which is a special value denoting a null pointer. This should be used instead of `0` or `NULL` to indicate a null pointer.
103
103
104
104
## Comments
105
105
@@ -123,12 +123,12 @@ int myFunc()
123
123
*/
124
124
```
125
125
126
-
which would be impossible if the function comment header used `/* */`
126
+
which would be impossible if the function comment header used `/* */`.
127
127
128
128
## Never Use `using namespace` in a Header File
129
129
130
-
This causes the name space you are `using` to be pulled into the namespace of the header file.
131
-
It litters the namespace and it may lead to name collisions in the future.
130
+
This causes the namespace you are `using` to be pulled into the namespace of all files that include the header file.
131
+
It pollutes the namespace and it may lead to name collisions in the future.
132
132
Writing `using namespace` in an implementation file is fine though.
133
133
134
134
@@ -157,21 +157,22 @@ Leaving them off can lead to semantic errors in the code.
157
157
158
158
```cpp
159
159
// Bad Idea
160
-
// this compiles and does what you want, but can lead to confusing
161
-
// errors if close attention is not paid.
160
+
// This compiles and does what you want, but can lead to confusing
161
+
// errors if modification are made in the future and close attention
162
+
// is not paid.
162
163
for (int i = 0; i < 15; ++i)
163
164
std::cout << i << std::endl;
164
165
165
166
// Bad Idea
166
-
//the cout is not part of the loop in this case even though it appears to be
167
+
//The cout is not part of the loop in this case even though it appears to be.
167
168
int sum = 0;
168
169
for (int i = 0; i < 15; ++i)
169
170
++sum;
170
171
std::cout << i << std::endl;
171
172
172
173
173
174
// Good Idea
174
-
// It's clear which statements are part of the loop (or if block, or whatever)
175
+
// It's clear which statements are part of the loop (or if block, or whatever).
175
176
int sum = 0;
176
177
for (int i = 0; i < 15; ++i) {
177
178
++sum;
@@ -205,26 +206,26 @@ It also makes it possible to have two separate files next to each other on one s
205
206
206
207
```cpp
207
208
// Bad Idea. Requires extra -I directives to the compiler
208
-
// and goes against standards
209
+
// and goes against standards.
209
210
#include<string>
210
211
#include<includes/MyHeader.hpp>
211
212
212
213
// Worse Idea
213
-
//requires potentially even more specific -I directives and
214
-
// makes code more difficult to package and distribute
214
+
//Requires potentially even more specific -I directives and
215
+
// makes code more difficult to package and distribute.
215
216
#include<string>
216
217
#include<MyHeader.hpp>
217
218
218
219
219
220
// Good Idea
220
-
//requires no extra params and notifies the user that the file
221
-
// is a local file
221
+
//Requires no extra params and notifies the user that the file
222
+
// is a local file.
222
223
#include<string>
223
224
#include"MyHeader.hpp"
224
225
```
225
226
226
227
## Initialize Member Variables
227
-
...with the member initializer list
228
+
...with the member initializer list.
228
229
229
230
```cpp
230
231
// Bad Idea
@@ -244,7 +245,7 @@ private:
244
245
// Good Idea
245
246
// C++'s member initializer list is unique to the language and leads to
246
247
// cleaner code and potential performance gains that other languages cannot
247
-
// match
248
+
// match.
248
249
class MyClass
249
250
{
250
251
public:
@@ -267,7 +268,7 @@ private:
267
268
```
268
269
inside the class body. This makes sure that no constructor ever "forgets" to initialize a member object.
269
270
270
-
Use brace initialization, it does not allow narrowing at compile-time:
271
+
Use brace initialization; it does not allow narrowing at compile-time:
271
272
```cpp
272
273
// Best Idea
273
274
@@ -283,16 +284,16 @@ Forgetting to initialize a member is a source of undefined behavior bugs which a
283
284
284
285
## Always Use Namespaces
285
286
286
-
There is almost never a reason to declare an identifier in the global namespaces. Instead, functions and classes should exist in an appropriately named namespace or in a class inside of a namespace. Identifiers which are placed in the global namespace risk conflicting with identifiers from other libraries (mostly C, which doesn't have namespaces).
287
+
There is almost never a reason to declare an identifier in the global namespace. Instead, functions and classes should exist in an appropriately named namespace or in a class inside of a namespace. Identifiers which are placed in the global namespace risk conflicting with identifiers from other libraries (mostly C, which doesn't have namespaces).
287
288
288
289
289
-
## Use the Correct Integer Type For stdlib Features
290
+
## Use the Correct Integer Type for Standard Library Features
290
291
291
-
The standard library generally returns `size_t` for anything related to size. What exactly `size_t` is, is implementation defined.
292
+
The standard library generally uses `std::size_t` for anything related to size. The size of `size_t` is implementation defined.
292
293
293
294
In general, using `auto` will avoid most of these issues, but not all.
294
295
295
-
Make sure you stick with the correct integer types and remain consistent with the C++ stdlib. It might not warn on the platform you are currently using, but it probably will when you change platforms.
296
+
Make sure you stick with the correct integer types and remain consistent with the C++ standard library. It might not warn on the platform you are currently using, but it probably will when you change platforms.
296
297
297
298
## Use .hpp and .cpp for Your File Extensions
298
299
@@ -302,7 +303,7 @@ One particularly large project ([OpenStudio](https://github.com/NREL/OpenStudio)
302
303
303
304
## Never Mix Tabs and Spaces
304
305
305
-
Some editors like to indent with a mixture of tabs and spaces by default. This makes the code unreadable to anyone not using the exact same tab indentation settings.
306
+
Some editors like to indent with a mixture of tabs and spaces by default. This makes the code unreadable to anyone not using the exact same tab indentation settings. Configure your editor so this does not happen.
306
307
307
308
## Never Put Code with Side Effects Inside an assert()
308
309
@@ -322,17 +323,17 @@ They should be preferred to macros, because macros do not honor namespaces, etc.
322
323
323
324
Operator overloading was invented to enable expressive syntax. Expressive in the sense that adding two big integers looks like `a + b` and not `a.add(b)`. Another common example is std::string, where it is very common to concatenate two strings with `string1 + string2`.
324
325
325
-
However, you can easily create unreadable expressions using too much or wrong operator overloading. When overloading operators, there are three basic rules to follow as described [on stackoverflow](http://stackoverflow.com/questions/4421706/operator-overloading/4421708#4421708)
326
+
However, you can easily create unreadable expressions using too much or wrong operator overloading. When overloading operators, there are three basic rules to follow as described [on stackoverflow](http://stackoverflow.com/questions/4421706/operator-overloading/4421708#4421708).
326
327
327
-
More detailed, you should keep these things in mind:
328
+
Specifically, you should keep these things in mind:
328
329
329
-
* Overloading `operator=` when handling with resources is a must, see[Consider the Rule of Zero](03-Style.md#consider-the-rule-of-zero) below.
330
+
* Overloading `operator=()` when handling resources is a must. See[Consider the Rule of Zero](03-Style.md#consider-the-rule-of-zero) below.
330
331
* For all other operators, only overload them when they are used in a context that is commonly connected to these operators. Typical scenarios are concatenating things with +, negating expressions that can be considered "true" or "false", etc.
331
-
* Always be aware of the [operator precedence](http://en.cppreference.com/w/cpp/language/operator_precedence) and try to circumvent unintuitive constructs.
332
+
* Always be aware of the [operator precedence](http://en.cppreference.com/w/cpp/language/operator_precedence) and try to circumvent unintuitive constructs.
332
333
* Do not overload exotic operators such as ~ or % unless implementing a numeric type or following a well recognized syntax in specific domain.
333
-
*[Never](http://stackoverflow.com/questions/5602112/when-to-overload-the-comma-operator?answertab=votes#tab-top) overload `operator ,` (the comma operator).
334
-
* Use `operator >>` and `operator <<` when dealing with streams. For example, you can overload `operator<<(std::ostream &, MyClass const &)` to enable "writing" you class into a stream, such as std::cout or an std::fstream or std::stringstream. The latter is often used to create a textual representation of a value.
335
-
* There are more common operators to overload [described here](http://stackoverflow.com/questions/4421706/operator-overloading?answertab=votes#tab-top)
334
+
*[Never](http://stackoverflow.com/questions/5602112/when-to-overload-the-comma-operator?answertab=votes#tab-top) overload `operator,()` (the comma operator).
335
+
* Use non-member functions `operator>>()` and `operator<<()` when dealing with streams. For example, you can overload `operator<<(std::ostream &, MyClass const &)` to enable "writing" your class into a stream, such as `std::cout` or an `std::fstream` or `std::stringstream`. The latter is often used to create a string representation of a value.
336
+
* There are more common operators to overload [described here](http://stackoverflow.com/questions/4421706/operator-overloading?answertab=votes#tab-top).
336
337
337
338
More tips regarding the implementation details of your custom operators can be found [here](http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html).
0 commit comments