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
Over the past 25 years, C++ has been one of the most widely used programming languages in the world. Well-written C++ programs are fast and efficient. The language is more flexible than other languages because it enables you to access low-level hardware features to maximize speed and minimize memory requirements. You can use it to create a wide range of apps—from games, to high-performance scientific software, to device drivers, embedded programs, libraries and compilers for other programming languages, Windows client apps, and much more.
9
+
Over the past 25 years, C++ has been one of the most widely used programming languages in the world. Well-written C++ programs are fast and efficient. The language is more flexible than other languages because it enables you to access low-level hardware features to maximize speed and minimize memory requirements. You can use it to create a wide range of apps—from games, to high-performance scientific software, device drivers, embedded programs, libraries and compilers for other programming languages, Windows client apps, and much more.
10
10
11
-
One of the original requirements for C++ was backward compatibility with the C language. As a result C++ has always permitted C-style programming with raw pointers, arrays, null-terminated character strings, custom data structures, and other features that may enable great performance but can also spawn bugs and complexity. The evolution of C++ has emphasized features that greatly reduce the need to C-style idioms. The old C-programming facilities are there when you need them, but with modern C++ code you should need them less and less. Modern C++ code is simpler, safer, more elegant, and still as fast as ever.
11
+
One of the original requirements for C++ was backward compatibility with the C language. As a result C++ has always permitted C-style programming with raw pointers, arrays, null-terminated character strings, custom data structures, and other features that may enable great performance but can also spawn bugs and complexity. The evolution of C++ has emphasized features that greatly reduce the need to use C-style idioms. The old C-programming facilities are there when you need them, but with modern C++ code you should need them less and less. Modern C++ code is simpler, safer, more elegant, and still as fast as ever.
12
12
13
13
The following sections provide an overview of the main features of modern C++. Unless noted otherwise, the features listed here are available in C++11 and later. In the Microsoft C++ compiler, you can set the [/std](../build/reference/std-specify-language-standard-version.md) compiler option to specify which version of the standard to use for your project.
14
14
15
-
## Prevent memory leaks through RAII and smart pointers
15
+
## RAII and smart pointers
16
16
17
-
One of the major classes of bugs in C-style programming is the *memory leak* due to failure to release memory or other resources. Modern C++ emphasizes the principle of *resource acquisition is initialization* which states that any resource (heap memory, file handles, sockets, and so on) should be *owned* by an object that creates, or receives, the newly-allocated resource in its constructor, and deletes in its destructor. By adhering to the principle of RAII, you guarantee that all resources will be properly returned to the operating system when the owning object goes out of scope. To support easy adoption of RAII principles, the C++ Standard Library provides three smart pointer types: [std::unique_ptr](../standard-library/unique-ptr-class.md), [std::shared_ptr](../standard-library/shared-ptr-class.md), and [std::weak_ptr](../standard-library/weak-ptr-class.md). A smart pointer handles the allocation and deletion of the memory it owns. The following example shows a class with an array member that is allocated on the heap in the call to `make_unique()`. The calls to **new** and **delete** are encapsulated by the `unique_ptr` class. When a `widget` object goes out of scope, the unique_ptr destructor will be invoked and it will release the memory that was allocated for the array.
17
+
One of the major classes of bugs in C-style programming is the *memory leak* due to failure to call **delete** for memory that was allocated with **new**. Modern C++ emphasizes the principle of *resource acquisition is initialization* which states that any resource (heap memory, file handles, sockets, and so on) should be *owned* by an object that creates, or receives, the newly-allocated resource in its constructor, and deletes it in its destructor. By adhering to the principle of RAII, you guarantee that all resources will be properly returned to the operating system when the owning object goes out of scope. To support easy adoption of RAII principles, the C++ Standard Library provides three smart pointer types: [std::unique_ptr](../standard-library/unique-ptr-class.md), [std::shared_ptr](../standard-library/shared-ptr-class.md), and [std::weak_ptr](../standard-library/weak-ptr-class.md). A smart pointer handles the allocation and deletion of the memory it owns. The following example shows a class with an array member that is allocated on the heap in the call to `make_unique()`. The calls to **new** and **delete** are encapsulated by the `unique_ptr` class. When a `widget` object goes out of scope, the unique_ptr destructor will be invoked and it will release the memory that was allocated for the array.
18
18
19
19
```cpp
20
20
#include<memory>
@@ -39,11 +39,11 @@ void functionUsingWidget() {
39
39
40
40
Whenever possible, use a smart pointer when allocating heap memory. If you must use the new and delete operators explicitly, follow the principle of RAII. For more information, see [Object lifetime and resource management (RAII)](object-lifetime-and-resource-management-modern-cpp.md).
41
41
42
-
## Use std::string and std::string_view instead of C-style char arrays
42
+
## std::string and std::string_view
43
43
44
44
C-style strings are another major source of bugs. By using [std::string and std::wstring](../standard-library/basic-string-class.md) you can eliminate virtually all the errors associated with C-style strings, and gain the benefit of member functions for searching, appending, prepending, and so on. Both are highly optimized for speed. When passing a string to a function that requires only read-only access, in (C++17) you can use [std::string_view](../standard-library/basic-string-view-class.md) for even greater performance benefit.
45
45
46
-
## Use std::vector and other Standard Library containers whenever possible
46
+
## std::vector and other Standard Library containers
47
47
48
48
The Standard Library containers all follow the principle of RAII, provide iterators for safe traversal of elements, are highly optimized for performance and have been thoroughly tested for correctness. By using these containers whenever possible, you eliminate the potential for bugs or inefficiencies that might be introduced in custom data structures. By default, use [vector](../standard-library/vector-class.md) as the preferred sequential container in C++. This is equivalent to `List<T>` in .NET languages.
49
49
@@ -70,15 +70,17 @@ When performance optimization is needed, consider using:
70
70
71
71
Don’t use C-style arrays. For older APIs that need direct access to the data, use accessor methods such as `f(vec.data(), vec.size());` instead. For more information about containers, see [C++ Standard Library Containers](../standard-library/stl-containers.md).
72
72
73
-
## Prefer Standard Library algorithms
73
+
## Standard Library algorithms
74
74
75
75
Before you assume that you need to write a custom algorithm for your program, first review the C++ Standard Library [algorithms](../standard-library/algorithm.md). The Standard Library contains an ever-growing assortment of algorithms for many common operations such as searching, sorting, filtering, and randomizing. The math library is extensive. Starting in C++17, parallel versions of many algorithms are provided.
76
76
77
77
Here are some important examples:
78
78
79
-
-**for_each**, which is the default traversal algorithm. (Also **transform** for not-in-place semantics.)
79
+
-**for_each**, the default traversal algorithm (along with range-based for loops).
80
80
81
-
-**find_if**, which is the default search algorithm.
81
+
-**transform**, for not-in-place modification of container elements
82
+
83
+
-**find_if**, the default search algorithm.
82
84
83
85
-**sort**, **lower_bound**, and the other default sorting and searching algorithms.
C++11 introduced the [auto](auto-cpp.md) keyword for use in variable, function, and template declarations. **auto** tells the compiler to deduce the type of the object so that you do not have to type it explicitly. **auto** is especially useful when the deduced type is a nested template:
99
101
@@ -102,7 +104,7 @@ map<int,list<string>>::iterator i = m.begin(); // C-style
102
104
auto i = m.begin(); // modern C++
103
105
```
104
106
105
-
## Use range-based for loops to eliminate indexing errors
107
+
## Range-based for loops
106
108
107
109
C-style iteration over arrays and containers is prone to indexing errors and is also tedious to type. To eliminate these errors, and make your code more readable, use range-based for loops with Standard Library containers as well as raw arrays. For more information, see [Range-based for statement](../cpp/range-based-for-statement-cpp.md).
108
110
@@ -128,7 +130,7 @@ int main()
128
130
}
129
131
```
130
132
131
-
### Use constexpr expressions instead of macros
133
+
## constexpr expressions instead of macros
132
134
133
135
Macros in C and C++ are tokens that are processed by the preprocessor prior to compilation. Each instance of a macro token is replaced with its defined value or expression before the file is compiled. Macros are commonly used in C-style programming to define compile-time constant values. However, macros are error-prone and difficult to debug. In modern C++, you should prefer [constexpr](constexpr-cpp.md) variables for compile-time constants:
134
136
@@ -174,11 +176,11 @@ int main()
174
176
175
177
For more information, see [Brace initialization](initializing-classes-and-structs-without-constructors-cpp.md).
176
178
177
-
## Move semantics to avoid unnecessary copies
179
+
## Move semantics
178
180
179
181
Modern C++ provides *move semantics* which make it possible to eliminate unnecessary memory copies which in earlier versions of the language were unavoidable in certain situations. A *move* operation transfers ownership of a resource from one object to the next without making a copy. When implementing a classthat owns a resource such as heap memory, file handles, and so on, you can define a *move constructor* and *move assignment operator* for it. The compiler will choose these special members during overload resolution in situations where a copy is not needed. The Standard Library container types invoke the move constructor on objects if one is defined. For more information, see [Move Constructors and Move Assignment Operators (C++)](move-constructors-and-move-assignment-operators-cpp.md).
180
182
181
-
## Lambda expressions instead of function pointers
183
+
## Lambda expressions
182
184
183
185
In C-style programming, a function can be passed to another function by means of a *function pointer*. Function pointers are inconvenient to maintain and understand because the function they refer to may be defined elsewhere in the source code, far away from the point at which it is being invoked. Also, they are not type-safe. Modern C++ provides function objects, classes that override the [()](function-call-operator-parens.md) operator which enables them to be called like a function. The most convenient way to create function objects is with inline [lambda expressions](../cpp/lambda-expressions-in-cpp.md). The following example shows how to use a lambda expression to pass a function object, that the `for_each` function will invoke on each element in the vector:
184
186
@@ -195,11 +197,11 @@ The lambda expression `[=](int i) { return i > x && i < y; }` can be read as "fu
195
197
196
198
As a general rule, modern C++ emphasizes exceptions rather than error codes as the best way to report and handle error conditions. For more information, see [Modern C++ best practices for exceptions and error handling](errors-and-exception-handling-modern-cpp.md).
197
199
198
-
## std::atomic for lock-free inter-thread communication
200
+
## std::atomic
199
201
200
202
Use the C++ Standard Library [std::atomic](../standard-library/atomic-structure.md) struct and related types for inter-thread communication mechanisms.
201
203
202
-
## std::variant instead of unions (C++17)
204
+
## std::variant (C++17)
203
205
204
206
Unions are commonly used in C-style programming to conserve memory by enabling members of different types to occupy the same memory location. However, unions are not type-safe and are prone to programming errors. C++17 introduces the [std::variant](../standard-library/variant-class.md) class as a more robust and safe alternative to unions. The [std::visit](../standard-library/variant-functions.md#visit) function can be used to access the members of a `variant` type in a type-safe manner.
0 commit comments