Willkommen zurück zur C++ modernenC++Welcome back to C++ - Modern C++

Seit seiner Erstellung C++ ist zu einer der am häufigsten verwendeten Programmiersprachen in der Welt geworden.Since its creation, C++ has become one of the most widely used programming languages in the world. Gut geschriebene C++-Programme sind schnell und effizient.Well-written C++ programs are fast and efficient. Die Sprache ist flexibler als andere Sprachen: Sie kann auf der höchsten Abstraktions Ebene und auf der Ebene des Silicon verwendet werden.The language is more flexible than other languages: It can work at the highest levels of abstraction, and down at the level of the silicon. C++bietet hochgradig optimierte Standardbibliotheken.C++ supplies highly optimized standard libraries. Sie ermöglicht den Zugriff auf Low-Level-Hardware Features, um die Geschwindigkeit zu maximieren und Arbeitsspeicher Anforderungen zu minimierenIt enables access to low-level hardware features, to maximize speed and minimize memory requirements. Mithilfe C++von können Sie eine große Bandbreite von apps erstellen.Using C++, you can create a wide range of apps. Spiele, Gerätetreiber und leistungsstarke wissenschaftliche Software.Games, device drivers, and high-performance scientific software. Eingebettete Programme.Embedded programs. Windows-Client-apps.Windows client apps. Auch Bibliotheken und Compiler für andere Programmiersprachen werden in C++geschrieben.Even libraries and compilers for other programming languages get written in C++.

Eine der ursprünglichen Anforderungen für C++ war Abwärtskompatibilität mit der Programmiersprache C.One of the original requirements for C++ was backward compatibility with the C language. Daher C++ hat die Programmierung im C-Stil stets mit unformatierten Zeigern, Arrays, auf NULL endenden Zeichen folgen und anderen Features gestattet.As a result, C++ has always permitted C-style programming, with raw pointers, arrays, null-terminated character strings, and other features. Sie können eine hohe Leistung ermöglichen, aber auch Fehler und Komplexität erzeugen.They may enable great performance, but can also spawn bugs and complexity. Die Entwicklung von C++ hat Features hervorgehoben, die die Notwendigkeit der Verwendung von Idioms im C-Stil erheblich verringern.The evolution of C++ has emphasized features that greatly reduce the need to use C-style idioms. Die alten Funktionen für die C-Programmierung sind vorhanden, wenn Sie Sie benötigen, C++ aber mit modernem Code sollten Sie Sie weniger und weniger benötigen.The old C-programming facilities are there when you need them, but with modern C++ code you should need them less and less. Moderner C++ Code ist einfacher, sicherer, eleganter und immer noch so schnell wie je zuvor.Modern C++ code is simpler, safer, more elegant, and still as fast as ever.

Die folgenden Abschnitte bieten einen Überblick über die wichtigsten Features von modern C++.The following sections provide an overview of the main features of modern C++. Sofern nicht anders angegeben, sind die hier aufgeführten Funktionen in c++ 11 und höher verfügbar.Unless noted otherwise, the features listed here are available in C++11 and later. Im Microsoft C++ -Compiler können Sie die /Std -Compileroption festlegen, um anzugeben, welche Version des Standards für das Projekt verwendet werden soll.In the Microsoft C++ compiler, you can set the /std compiler option to specify which version of the standard to use for your project.

Ressourcen und intelligente ZeigerResources and smart pointers

Eine der Hauptklassen von Fehlern bei der Programmierung im C-Stil ist der SpeicherFehler.One of the major classes of bugs in C-style programming is the memory leak. Verluste werden häufig durch einen Fehler beim Abrufen von Delete für den Arbeitsspeicher verursacht, der mit Newzugeordnet wurde.Leaks are often caused by a failure to call delete for memory that was allocated with new. Modern C++ betont das Prinzip der Ressourcenbeschaffung ist Initialisierung (RAII).Modern C++ emphasizes the principle of resource acquisition is initialization (RAII). Die Idee ist einfach.The idea is simple. Ressourcen (Heap Speicher, Datei Handles, Sockets usw.) sollten im Besitz eines Objekts sein.Resources (heap memory, file handles, sockets, and so on) should be owned by an object. Dieses Objekt erstellt bzw. empfängt die neu zugeordnete Ressource im Konstruktor und löscht sie in Ihrem Dekonstruktor.That object creates, or receives, the newly allocated resource in its constructor, and deletes it in its destructor. Das Prinzip von RAII stellt sicher, dass alle Ressourcen ordnungsgemäß an das Betriebssystem zurückgegeben werden, wenn das besitzende Objekt den Gültigkeitsbereich verlässt.The principle of RAII guarantees that all resources get properly returned to the operating system when the owning object goes out of scope.

Zur Unterstützung der einfachen Übernahme von RAII- C++ Prinzipien bietet die Standard Bibliothek drei intelligente Zeiger Typen: Std:: unique_ptr, Std:: shared_ptrund Std:: weak_ptr.To support easy adoption of RAII principles, the C++ Standard Library provides three smart pointer types: std::unique_ptr, std::shared_ptr, and std::weak_ptr. Ein intelligenter Zeiger übernimmt die Zuordnung und Löschung des Arbeitsspeichers, den er besitzt.A smart pointer handles the allocation and deletion of the memory it owns. Im folgenden Beispiel wird eine-Klasse mit einem Array Element veranschaulicht, das im-make_unique()aufgerufen wird.The following example shows a class with an array member that is allocated on the heap in the call to make_unique(). Die Aufrufe von New und Delete werden von der unique_ptr-Klasse gekapselt.The calls to new and delete are encapsulated by the unique_ptr class. Wenn ein widget Objekt den Gültigkeitsbereich verlässt, wird der unique_ptr Dekonstruktor aufgerufen und gibt den Arbeitsspeicher frei, der für das Array reserviert wurde.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.

#include <memory>
class widget
{
private:
    std::unique_ptr<int> data;
public:
    widget(const int size) { data = std::make_unique<int>(size); }
    void do_something() {}
};

void functionUsingWidget() {
    widget w(1000000);   // lifetime automatically tied to enclosing scope
                // constructs w, including the w.data gadget member
    // ...
    w.do_something();
    // ...
} // automatic destruction and deallocation for w and w.data

Verwenden Sie nach Möglichkeit einen intelligenten Zeiger, wenn Sie Heap Speicher zuordnen.Whenever possible, use a smart pointer when allocating heap memory. Wenn Sie die Operatoren "New" und "Delete" explizit verwenden müssen, befolgen Sie das Prinzip von RAII.If you must use the new and delete operators explicitly, follow the principle of RAII. Weitere Informationen finden Sie unter Objekt Lebensdauer und Ressourcenverwaltung (RAII).For more information, see Object lifetime and resource management (RAII).

Std:: String und Std:: string_viewstd::string and std::string_view

Zeichen folgen im C-Stil sind eine weitere wichtige Quelle für Fehler.C-style strings are another major source of bugs. Durch die Verwendung von Std:: String und Std:: wstringkönnen Sie praktisch alle Fehler beseitigen, die mit Zeichen folgen im C-Stil verknüpft sind.By using std::string and std::wstring, you can eliminate virtually all the errors associated with C-style strings. Außerdem profitieren Sie von den Vorteilen der Element Funktionen zum Suchen, anfügen, voranstellen usw.You also gain the benefit of member functions for searching, appending, prepending, and so on. Beide sind für die Geschwindigkeit stark optimiert.Both are highly optimized for speed. Wenn Sie eine Zeichenfolge an eine Funktion übergeben, die nur schreibgeschützten Zugriff erfordert, können Sie in c++ 17 Std:: string_view für einen noch größeren Leistungsvorteil verwenden.When passing a string to a function that requires only read-only access, in C++17 you can use std::string_view for even greater performance benefit.

Std:: Vector und andere Standard Bibliotheks Containerstd::vector and other Standard Library containers

Die Standard Bibliotheks Container befolgen alle das Prinzip von RAII.The Standard Library containers all follow the principle of RAII. Sie stellen Iteratoren für den sicheren Durchlauf von Elementen bereit.They provide iterators for safe traversal of elements. Und Sie sind stark für die Leistung optimiert und wurden gründlich auf Richtigkeit getestet.And, they're highly optimized for performance and have been thoroughly tested for correctness. Wenn Sie diese Container verwenden, vermeiden Sie das Potenzial von Fehlern oder Ineffizienzen, die in benutzerdefinierten Datenstrukturen eingeführt werden könnten.By using these containers, you eliminate the potential for bugs or inefficiencies that might be introduced in custom data structures. Verwenden Sie anstelle von unformatierten Arrays Vector als sequenziellen C++Container in.Instead of raw arrays, use vector as a sequential container in C++.

vector<string> apples;
apples.push_back("Granny Smith");

Verwenden Sie map (nicht unordered_map) als standardmäßigen assoziativen Container.Use map (not unordered_map) as the default associative container. Verwenden Sie Set, multimapund Multiset für degenerierte und mehrere Fälle.Use set, multimap, and multiset for degenerate and multi cases.

map<string, string> apple_color;
// ...
apple_color["Granny Smith"] = "Green";

Wenn eine Leistungsoptimierung erforderlich ist, erwägen Sie folgende Verwendungen:When performance optimization is needed, consider using:

  • Der Arraytyp beim einbetten ist wichtig, z. b. als Klassenmember.The array type when embedding is important, for example, as a class member.

  • Ungeordnete assoziative Container, z. b. unordered_map.Unordered associative containers such as unordered_map. Diese verfügen über einen niedrigeren pro-Element-Aufwand und eine Konstante Zeit Suche, Sie können jedoch schwieriger und effizient verwendet werden.These have lower per-element overhead and constant-time lookup, but they can be harder to use correctly and efficiently.

  • Sortiertes vector.Sorted vector. Weitere Informationen finden Sie unter Algorithmen.For more information, see Algorithms.

Verwenden Sie keine Arrays im C-Stil.Don’t use C-style arrays. Verwenden Sie für ältere APIs, die direkten Zugriff auf die Daten benötigen, Zugriffsmethoden wie z. b. f(vec.data(), vec.size());.For older APIs that need direct access to the data, use accessor methods such as f(vec.data(), vec.size()); instead. Weitere Informationen zu Containern finden C++ Sie unter Standard Bibliothek Container.For more information about containers, see C++ Standard Library Containers.

Algorithmen der Standard BibliothekStandard Library algorithms

Bevor Sie davon ausgehen, dass Sie einen benutzerdefinierten Algorithmus für Ihr Programm schreiben müssen, über C++ prüfen Sie zunächst die Algorithmender Standard Bibliothek.Before you assume that you need to write a custom algorithm for your program, first review the C++ Standard Library algorithms. Die Standard Bibliothek enthält ein ständig wachsendes Spektrum an Algorithmen für viele gängige Vorgänge wie das suchen, sortieren, Filtern und randomialisieren.The Standard Library contains an ever-growing assortment of algorithms for many common operations such as searching, sorting, filtering, and randomizing. Die mathematische Bibliothek ist umfangreich.The math library is extensive. Ab c++ 17 werden parallele Versionen von vielen Algorithmen bereitgestellt.Starting in C++17, parallel versions of many algorithms are provided.

Im Folgenden sind einige wichtige Beispiele aufgeführt:Here are some important examples:

  • for_each, der standardmäßige Traversale-Algorithmus (zusammen mit Bereichs basierten for-Schleifen).for_each, the default traversal algorithm (along with range-based for loops).

  • Transformationfür nicht direkte Änderungen von Container Elemententransform, for not-in-place modification of container elements

  • find_if, der Standard Suchalgorithmus.find_if, the default search algorithm.

  • Sortieren, lower_boundund die anderen standardmäßigen Sortier-und Suchalgorithmen.sort, lower_bound, and the other default sorting and searching algorithms.

Verwenden Sie zum Schreiben eines Comparators Strict < , und verwenden Sie benannte Lambdas , wenn dies möglich ist.To write a comparator, use strict < and use named lambdas when you can.

auto comp = [](const widget& w1, const widget& w2)
     { return w1.weight() < w2.weight(); }

sort( v.begin(), v.end(), comp );

auto i = lower_bound( v.begin(), v.end(), comp );

Auto anstelle von expliziten Typnamenauto instead of explicit type names

C++ 11 hat das Schlüsselwort " Auto " zur Verwendung in Variablen-, Funktions-und Vorlagen Deklarationen eingeführt.C++11 introduced the auto keyword for use in variable, function, and template declarations. Auto weist den Compiler an, den Typ des Objekts abzuleiten, damit Sie ihn nicht explizit eingeben müssen.auto tells the compiler to deduce the type of the object so that you don't have to type it explicitly. " Auto " ist besonders nützlich, wenn der dedulierte Typ eine in einer Vorlage vorgenommene Vorlage ist:auto is especially useful when the deduced type is a nested template:

map<int,list<string>>::iterator i = m.begin(); // C-style
auto i = m.begin(); // modern C++

Bereichsbasierte For-SchleifenRange-based for loops

Die Iterationen im C-Stil für Arrays und Container sind anfällig für das Indizieren von Fehlern und auch mühsam.C-style iteration over arrays and containers is prone to indexing errors and is also tedious to type. Um diese Fehler zu vermeiden und den Code lesbarer zu machen, verwenden Sie Bereichs basierte for-Schleifen mit Standard Bibliotheks Containern und unformatierten Arrays.To eliminate these errors, and make your code more readable, use range-based for loops with both Standard Library containers and raw arrays. Weitere Informationen finden Sie unter Range-based for-Anweisung.For more information, see Range-based for statement.

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v {1,2,3};

    // C-style
    for(int i = 0; i < v.size(); ++i)
    {
        std::cout << v[i];
    }

    // Modern C++:
    for(auto& num : v)
    {
        std::cout << num;
    }
}

constexpr-Ausdrücke anstelle von Makrosconstexpr expressions instead of macros

Makros in C und C++ sind Token, die vom Präprozessor vor der Kompilierung verarbeitet werden.Macros in C and C++ are tokens that are processed by the preprocessor before compilation. Jede Instanz eines Makro Tokens wird durch den definierten Wert oder Ausdruck ersetzt, bevor die Datei kompiliert wird.Each instance of a macro token is replaced with its defined value or expression before the file is compiled. Makros werden häufig bei der Programmierung im C-Stil verwendet, um konstante Werte für die Kompilierzeit zu definieren.Macros are commonly used in C-style programming to define compile-time constant values. Makros sind jedoch fehleranfällig und schwer zu debuggen.However, macros are error-prone and difficult to debug. In modernen C++Erweiterungen sollten Sie constexpr -Variablen für Kompilierzeit Konstanten bevorzugen:In modern C++, you should prefer constexpr variables for compile-time constants:

#define SIZE 10 / C-style
constexpr int size = 10; // modern C++

Einheitliche InitialisierungUniform initialization

In modernen C++können Sie die Initialisierung von Klammern für beliebige Typen verwenden.In modern C++, you can use brace initialization for any type. Diese Form der Initialisierung ist besonders praktisch, wenn Arrays, Vektoren oder andere Container initialisiert werden.This form of initialization is especially convenient when initializing arrays, vectors, or other containers. Im folgenden Beispiel wird v2 mit drei Instanzen von Sinitialisiert.In the following example, v2 is initialized with three instances of S. v3 wird mit drei Instanzen von S initialisiert, die selbst mit geschweiften Klammern initialisiert werden.v3 is initialized with three instances of S that are themselves initialized using braces. Der Compiler leitet den Typ jedes Elements auf der Grundlage des deklarierten Typs v3ab.The compiler infers the type of each element based on the declared type of v3.

#include <vector>

struct S
{
    std::string name;
    float num;
    S(std::string s, float f) : name(s), num(f) {}
};

int main()
{
    // C-style initialization
    std::vector<S> v;
    S s1("Norah", 2.7);
    S s2("Frank", 3.5);
    S s3("Jeri", 85.9);

    v.push_back(s1);
    v.push_back(s2);
    v.push_back(s3);

    // Modern C++:
    std::vector<S> v2 {s1, s2, s3};

    // or...
    std::vector<S> v3{ {"Norah", 2.7}, {"Frank", 3.5}, {"Jeri", 85.9} };

}

Weitere Informationen finden Sie unter geschweifter Klammer Initialisierung.For more information, see Brace initialization.

Verschieben der SemantikMove semantics

Modern C++ bietet Bewegungs Semantik, sodass unnötige Speicher Kopien vermieden werden können.Modern C++ provides move semantics, which make it possible to eliminate unnecessary memory copies. In früheren Versionen der Sprache waren Kopien in bestimmten Situationen unvermeidlich.In earlier versions of the language, copies were unavoidable in certain situations. Ein Verschiebungs Vorgang überträgt den Besitz einer Ressource von einem Objekt zum nächsten, ohne eine Kopie zu erstellen.A move operation transfers ownership of a resource from one object to the next without making a copy. Beim Implementieren einer Klasse, die eine Ressource besitzt (z. b. Heap Speicher, Datei Handles usw.), können Sie einen bewegungskonstruktor und Verschiebungs Zuweisungs Operator dafür definieren.When implementing a class that owns a resource (such as heap memory, file handles, and so on), you can define a move constructor and move assignment operator for it. Der Compiler wählt diese speziellen Member bei der Überladungs Auflösung in Situationen aus, in denen eine Kopie nicht benötigt wird.The compiler will choose these special members during overload resolution in situations where a copy isn't needed. Die Containertypen der Standard Bibliothek rufen den bewegungskonstruktor für Objekte auf, wenn eine definiert ist.The Standard Library container types invoke the move constructor on objects if one is defined. Weitere Informationen finden Sie unter bewegungskonstruktoren und Bewegungs ZuweisungsC++Operatoren ().For more information, see Move Constructors and Move Assignment Operators (C++).

LambdaausdrückeLambda expressions

Bei der Programmierung im C-Stil kann eine Funktion mithilfe eines Funktions Zeigersan eine andere Funktion übermittelt werden.In C-style programming, a function can be passed to another function by using a function pointer. Funktionszeiger sind unpraktisch für die Wartung und das Verständnis.Function pointers are inconvenient to maintain and understand. Die Funktion, auf die Sie verweisen, kann an anderer Stelle im Quellcode definiert werden, und zwar weit entfernt von dem Zeitpunkt, an dem Sie aufgerufen wird.The function they refer to may be defined elsewhere in the source code, far away from the point at which it's invoked. Außerdem sind Sie nicht typsicher.Also, they're not type-safe. Modern C++ bietet Funktions Objekte, Klassen, die den Operator () überschreiben, sodass Sie wie eine Funktion aufgerufen werden können.Modern C++ provides function objects, classes that override the () operator, which enables them to be called like a function. Die einfachste Möglichkeit zum Erstellen von Funktions Objekten ist die Verwendung von Inline- Lambda-Ausdrücken.The most convenient way to create function objects is with inline lambda expressions. Im folgenden Beispiel wird gezeigt, wie ein Lambda-Ausdruck verwendet wird, um ein Funktions Objekt zu übergeben, das die for_each-Funktion für jedes Element im Vektor aufruft: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:

    std::vector<int> v {1,2,3,4,5};
    int x = 2;
    int y = 4;
    auto result = find_if(begin(v), end(v), [=](int i) { return i > x && i < y; });

Der Lambda-Ausdruck [=](int i) { return i > x && i < y; } kann als "Funktion gelesen werden, die ein einzelnes Argument vom Typ int annimmt und einen booleschen Wert zurückgibt, der angibt, ob das Argument größer als x und kleiner als yist."The lambda expression [=](int i) { return i > x && i < y; } can be read as "function that takes a single argument of type int and returns a boolean that indicates whether the argument is greater than x and less than y." Beachten Sie, dass die Variablen x und y aus dem umgebenden Kontext im Lambda-Ausdruck verwendet werden können.Notice that the variables x and y from the surrounding context can be used in the lambda. Der [=] gibt an, dass diese Variablen nach Wert aufgezeichnet werden. Das heißt, der Lambda Ausdruck hat seine eigenen Kopien dieser Werte.The [=] specifies that those variables are captured by value; in other words, the lambda expression has its own copies of those values.

AusnahmenExceptions

Modern C++ unterstreicht Ausnahmen anstelle von Fehlercodes als beste Methode zum melden und behandeln von Fehlerbedingungen.Modern C++ emphasizes exceptions rather than error codes as the best way to report and handle error conditions. Weitere Informationen finden Sie unter moderne C++ bewährte Methoden für Ausnahmen und Fehlerbehandlung.For more information, see Modern C++ best practices for exceptions and error handling.

Std:: Atomicstd::atomic

Verwenden Sie C++ die Standard Bibliothek Std:: Atomic -Struktur und verwandte Typen für Kommunikationsmechanismen zwischen Threads.Use the C++ Standard Library std::atomic struct and related types for inter-thread communication mechanisms.

Std:: Variant (c++ 17)std::variant (C++17)

Unions werden häufig bei der Programmierung im C-Stil verwendet, um Speicherplatz zu sparen, indem die Mitglieder verschiedener Typen die gleiche Speicheradresse belegen können.Unions are commonly used in C-style programming to conserve memory by enabling members of different types to occupy the same memory location. Allerdings sind Unions nicht typsicher und anfällig für Programmierfehler.However, unions aren't type-safe and are prone to programming errors. C++ 17 führt die Std:: Variant -Klasse als stabilere und sicherere Alternative zu Unions ein.C++17 introduces the std::variant class as a more robust and safe alternative to unions. Die Std:: Visit -Funktion kann verwendet werden, um auf typsichere Weise auf Member eines variant Typs zuzugreifen.The std::visit function can be used to access the members of a variant type in a type-safe manner.

Siehe auchSee also

C++ Language Reference (C++-Programmiersprachenreferenz)C++ Language Reference
Lambda-AusdrückeLambda Expressions
C++-StandardbibliothekC++ Standard Library
Microsoft C++-Sprachkonformität: TabelleMicrosoft C++ language conformance table