[C++/de] fixed wrong spelling (#3579)

* Added [C++/de]

* [C++/de] filename fixed.

* [C++/de] language code in filename added

* [C++/de] fixed wrong spelling

* [C++/en] smart pointer added
This commit is contained in:
LamdaLamdaLamda 2019-08-03 20:18:39 +02:00 committed by Divay Prakash
parent 7fca9b47a9
commit 41f2b7f168
2 changed files with 157 additions and 110 deletions

View File

@ -761,7 +761,7 @@ failure:
// things are a little cleaner, but still sub-optimal.
void doSomethingWithAFile(const char* filename)
{
FILE* fh = fopen(filename, "r"); // Open the file in read mode
FILE* fh = fopen(filename, "r"); // Open the file in shared_ptrread mode
if (fh == nullptr)
throw std::runtime_error("Could not open the file.");
@ -814,6 +814,57 @@ void doSomethingWithAFile(const std::string& filename)
// - Mutexes using lock_guard and unique_lock
/////////////////////
// Smart Pointer
/////////////////////
// Generally a smart pointer is a class, which wraps a "raw pointer" (usage of "new"
// respectively malloc/calloc in C). The goal is to be able to
// manage the lifetime of the object being point to without explicitly deleting
// the object. The term itself simply describes a set of pointers with the
// mentioned abstraction.
// Basically smart pointers should preferred over raw pointers, to prevent
// risky memory leaks, which happens if you forget to delete the object.
// Usage of a raw pointer:
Dog* ptr = new Dog();
ptr->bark();
delete ptr;
// With the usage of smart pointers you dont have to worry about the deletion
// of a object anymore.
// A smart pointer describes a policy, to count the references on the
// pointer. As matter of fact the objects gets destroyed when the last
// reference on the object gets destroyed.
// Usage of "std::shared_ptr":
void foo()
{
// Its not longer necessary to delete the Dog.
std::shared_ptr<Dog> doggo(new Dog());
doggo->bark();
}
// Beware of possible circular references!!!
// There will be always a reference, so it will be never destroyed!
std::shared_ptr<Dog> doggo_one (new Dog());
std::shared_ptr<Dog> doggo_two (new Dog());
doggo_one = doggo_two; // p1 references p2
doggo_two = doggo_one; // p2 references p1
// As mentioned before there is a set of smart pointers. The way you have to
// use it, is always the same.
// This leads us to question, when to use which one?
// std::unique_ptr - use it when you just want to hold one reference on
// the same object.
// std::shared_ptr - use it when you want to hold multiple references on the
// same object and want to make sure that it´s de-allocated
// when all refences are gone.
// std::weak_ptr - use it when you want to hold multiple references from
// different places for references for which it´s no problem
// tp de-allocate.
/////////////////////
// Containers
/////////////////////

View File

@ -23,9 +23,11 @@ entworfen wurde um,
- generische Programmierung zu unterstützen
Durch seinen Syntax kann sie durchaus schwieriger und komplexer als neuere Sprachen sein.
Sie ist weit verbeitet, weil sie in Maschinen-Code compiliert, welches direkt vom Prozessor ausgeführt
Sie ist weit verbreitet, weil sie in Maschinen-Code kompiliert, welches direkt vom Prozessor ausgeführt
werden kann und somit eine strikte Kontrolle über die Hardware bietet und gleichzeitig
High-Level-Features wie generics, exceptions und Klassen enthält. (wie C)
High-Level-Features wie generics, exceptions und Klassen enthält.
Diese Kombination aus Geschwindigkeit und Funktionalität bildet C++ und ist eine der
weitverbreitesten Programmiersprachen.
@ -34,11 +36,12 @@ weitverbreitesten Programmiersprachen.
// Vergleich zu C
//////////////////
// C++ ist fast eine Untermenge von C and teilt sich grundsätzlich den
// C ist fast eine Untermenge von C++ und teilt sich grundsätzlich den
// Syntax für Variablen Deklarationen, primitiven Typen und Funktionen.
// Wie in C ist der Programmeinsprungpunkt eine Funktion, welche "main" genannt wird und
// einen Ineteger als Rückgabetyp besitzt.
// einen Integer als Rückgabetyp besitzt.
// Dieser Wert fungiert als Beendigungsstatus des Programms.
// Siehe: https://de.wikipedia.org/wiki/Return_Code für weitere Informationen
int main(int argc, char** argv)
@ -46,7 +49,7 @@ int main(int argc, char** argv)
// Kommandozeilen Argumente werden genauso wie in C über argc und argv übergeben
// argc entspricht der Anzahl von Argumenten und argv ist ein Array von C-style
// strings (char*), welche die Argumente repräsentieren.
// Das erste Argument ist der Name des Programms welches aufgerufen wird.
// Das erste Argument ist der Name des Programms, welches aufgerufen wird.
// Argc und argv können, wenn nicht benötigt, weg gelassen werden, indem
// die Funktionssignatur "int main()" verwendet wird.
@ -54,12 +57,12 @@ int main(int argc, char** argv)
return 0;
}
// C++ unterscheidet sich in einigen Punkten:
// C++ unterscheidet sich in einigen Punkten von C:
// In C++ sind Zeichen-Literale chars
// In C++ sind Zeichen-Literale char´s
sizeof('c') == sizeof(char) == 1
// In C sind Zeichen-Literale ints
// In C sind Zeichen-Literale int´s
sizeof('c') == sizeof(int)
// C++ verwendet striktes prototyping
@ -71,7 +74,7 @@ void func(); // Funktion mit beliebiger Anzahl von Argumenten
// Verwende nullptr, anstatt von NULL!!!
int* ip = nullptr;
// C standard headers sind in C++ verfügbar.
// C standard header sind in C++ verfügbar.
// C header enden mit .h, während
// C++ header das Präfix "c" besitzen und kein ".h" Suffix verwenden.
@ -115,10 +118,9 @@ int main()
// Argumente können per Standard für eine Funktion gesetzt werden,
// wenn diese beim Aufruf nicht bereitgestellt werden.
void doSomethingWithInts(int a = 1, int b = 4)
{
// führe Anweisungen mit "ints" aus.
// führe Anweisungen mit "int´s" aus.
}
int main()
@ -149,8 +151,8 @@ namespace First
{
printf("This is First::Nested::foo\n");
}
} // Ende des Namespaces "Nested"
} // Ende des Namespaces "First"
} // Ende des Namespace "Nested"
} // Ende des Namespace "First"
namespace Second
{
@ -236,7 +238,7 @@ cout << myString; // "Hello Dog"
// C++ besitzt _Referenzen_.
// Diese sind Pointer-Typen, welche nicht erneut zugewiesen werden können
// und nicht Null sein können.
// Sie besitzen den selben Synthax wie Variablen.
// Sie besitzen den selben Syntax wie Variablen.
// Für die Dereferenzierung ist kein * notwendig und
// & (die Adresse) wird nicht für die Zuweisung verwendet.
@ -261,19 +263,18 @@ cout << fooRef; // Gibt "I am bar" aus
// Die Adresse von fooRef verbleibt die selbe, sie verweist immer noch auf foo
const string& barRef = bar; // Erzeugt konstante Referenz auf bar.
// Wie in C, können konstante Werte ( und Pointer bzw. Referenzen) nicht verändert werden.
barRef += ". Hi!"; // Fehler: konstante Referenzen können nicht verändert werden.
// Hinweis: bevor wir genauer Referenzen besprechen, schauen wir uns zuerst ein Konzept an
// Hinweis: bevor wir genauer Referenzen besprechen, schauen wir uns zuerst ein Konzept an,
// welches als "temporäres Objekt" bezeichnet wird. Gehen wir von folgenden Code aus:
string tempObjectFun() { ... }
string retVal = tempObjectFun();
// Was passiert nun in der zweiten Zeile:
// - ein String Objekt wird von tempObjectFun zurückgegeben
// - ein String Objekt wird von "tempObjectFun" zurückgegeben
// - ein neuer String wird mit dem zurückgegebenen Objekt als Argument für den Konstruktor erzeugt.
// - das zurückgegebene Objekt wird zerstört
// Das zurückgegbene Objekt wird temporäres Objekt genannt. Temporäre Objekte werden erzeugt
@ -285,9 +286,9 @@ foo(bar(tempObjectFun()))
// Nehmen wir an foo und bar existieren. Das Objekt wird von "tempObjectFun" zurückgegeben,
// wird an bar übergeben und ist zerstört bevor foo aufgerufen wird.
// Zurück zu Referenzen. Die Ausnahme, dass die "am Ende des Ausdrucks" Regel ist gültig,
// wenn das temporäre Objekt an eine konstante Referenz gebunden ist, in welchem Fall das
// Leben auf den aktuellen Gültigkeitsbereich erweitert wird.
// Zurück zu Referenzen. Die Annahme, dass die "am Ende des Ausdrucks" Regel gültig ist,
// wenn das temporäre Objekt an eine konstante Referenz gebunden ist, ist der Fall, wenn die Lebensdauer
// auf den aktuellen Gültigkeitsbereich erweitert wird.
void constReferenceTempObjectFun() {
// constRef erhält das temporäre Objekt und ist gültig bis ans Ende der Funktion
@ -295,9 +296,10 @@ void constReferenceTempObjectFun() {
...
}
// Eine andere Art von Referenzen wird in C++11 eingeführt und ist speziell für
// Eine andere Art von Referenzen wurde in C++11 eingeführt und ist speziell für
// temporäre Objekte. Es ist nicht möglich Variablen des Typs zu besitzen, aber
// Vorrechte bei der Auflösung.
// Vorrechte bei der Auflösung zu besitzen.
void someFun(string& s) { ... } // Reguläre Referenz
void someFun(string&& s) { ... } // Referenz auf ein temporäres Objekt
@ -346,17 +348,17 @@ enum ECarTypes : uint8_t
void WriteByteToFile(uint8_t InputValue)
{
// Serialisierung von InputValue in eine Datei
// Serialisierung von "InputValue" in eine Datei
}
void WritePreferredCarTypeToFile(ECarTypes InputCarType)
{
// Das enum wird implizit zu einem "uint8_t" konvertiert. Bedingt dadurch, dass
// es sich um ein enum handelt.
// es sich um ein "enum" handelt.
WriteByteToFile(InputCarType);
}
// Nicht immer ist es gewünscht, dass enums zu einem Integer oder zu einem anderen
// Nicht immer ist es gewünscht, dass enum´s zu einem Integer oder zu einem anderen
// enum umgewandelt werden. Daher ist es möglich eine enum-Klasse zu erzeugen, welche
// nicht implizit umgewandelt wird.
enum class ECarTypes : uint8_t
@ -374,7 +376,7 @@ void WriteByteToFile(uint8_t InputValue)
void WritePreferredCarTypeToFile(ECarTypes InputCarType)
{
// Wird nicht kompilieren, da ECarTypes ein "uint8_t" ist, da das enum
// Wird nicht kompilieren, da "ECarTypes" ein "uint8_t" ist, da das enum
// als "enum class" deklariert wurde!
WriteByteToFile(InputCarType);
}
@ -401,14 +403,14 @@ public:
// Standard Konstruktor
Dog();
// Member-Funktonensdeklaration (Implementierung folgt)
// Member-Funktionsdeklaration (Implementierung folgt).
// Bemerkung: std::string statt der Verwendung von namespace std;
// "using namespace" sollte niemals in einem header verwendet werden.
void setName(const std::string& dogsName);
void setWeight(int dogsWeight);
// Funktionen, die Objekte nicht ändern sollte mit const deklariert werden.
// Funktionen, die Objekte nicht ändern, sollten mit const deklariert werden.
// Funktionen müssen explizit als "virtual" deklariert werden, um in einer
// abgeleiteten Klassen überschrieben zu werden.
// Aus performance Gründen sind Funktionen nicht per default virtual.
@ -430,7 +432,7 @@ public:
}; // Ein Semikolon schließt die Definition der Klasse ab.
// Klassen-Member-Funktionen sind üblicherweise in der .cpp Datei implmentiert.
// Klassen-Member-Funktionen sind üblicherweise in der .cpp Datei implementiert.
Dog::Dog()
{
std::cout << "A dog has been constructed\n";
@ -468,8 +470,6 @@ int main()
return 0;
} // Ausgabe: "Goodbye Barkley"
// Vererbung:
// Diese Klasse erbt alles was public bzw. protected ist von der Dog-Klasse
// und darüber hinaus auch private Methoden/Attribute, jedoch kann auf diese
// nicht direkt zugegriffen werden. Lediglich über public/procted getter/setter.
@ -588,7 +588,7 @@ public:
void insert(const T&) { ... }
};
// Während der Kompilierung generiert der Kompiler Kopien für jedes Template, wobei
// Während der Kompilierung generiert der Compiler Kopien für jedes template, wobei
// hierbei die Parameter substituiert werden. Somit muss bei jedem Aufruf die gesamte
// Definition der Klasse zur Verfügung stehen. Aus diesem Grund wird ein Template
// komplett im header definiert.
@ -623,7 +623,7 @@ void barkThreeTimes(const T& input)
// Hierbei ist zu beachten, dass an dieser Stelle nichts über den Typen des Parameters
// definiert wurde. Der Kompiler wird bei jedem Aufruf bzw. jeder Erzeugung den Typen
// prüfen. Somit funktioniert die zuvor definiert Funktion für jeden Typ 'T', die die
// prüfen. Somit funktioniert die zuvor definierte Funktion für jeden Typ 'T', die die
// const Methode 'bark' implementiert hat.
Dog fluffy;
@ -655,17 +655,17 @@ printMessage<10>(); // Gibt "Learn C++ faster in only 10 minutes!" aus.
// Ausnahme Behandlungen (Exception-Handling)
/////////////////////
// Die Standard Bibliothek bietet einige Exceptions.
// Die Standard Bibliothek bietet einige exceptions.
// Siehe: http://en.cppreference.com/w/cpp/error/exception.
// Grundsätzlich können alle Typen als Exception geworfen werden.
// Grundsätzlich können alle Typen als exception geworfen werden.
#include <exception>
#include <stdexcept>
// Alle Exceptions, die in dem "try" Block geworfen werden, können mittels
// Alle exceptions, die in dem "try" Block geworfen werden, können mittels
// "catch" abgefangen werden.
try
{
// Exceptions sollten nicht auf dem heap mithilfe
// exceptions sollten nicht auf dem heap mithilfe
// von "new" allokiert werden.
throw std::runtime_error("A problem occurred");
}
@ -775,7 +775,7 @@ void doSomethingWithAFile(const char* filename)
// Im Fehlerfall sollte sichergestellt sein, dass die
// Datei geschlossen wird.
fclose(fh);
throw; // Erneutes werfen der Exception
throw; // Erneutes werfen der exception
}
fclose(fh); // Schließen der Datei
@ -804,7 +804,7 @@ void doSomethingWithAFile(const std::string& filename)
// Der Destruktor wird das Datei-Handle im Hintergrund schließen und der
// Programmierer muss sich darum keinerlei Sorgen machen.
// 3. Der Code ist "exception sicher".
// Egal wo die exception geworfen wird, das Aufäumen wird definitv vollzogen.
// Egal wo die exception geworfen wird, das Aufräumen wird definitiv vollzogen.
// Der gesamte idiomatische C++ Code verwendet RAII für alle Ressourcen.
// Weitere Beispiele:
@ -818,7 +818,7 @@ void doSomethingWithAFile(const std::string& filename)
// Container
/////////////////////
// Die Container der Standard Tenplate Bibliothek beinhaltet einige vordefinierter templates.
// Die Container der Standard template Bibliothek beinhaltet einige vordefinierter templates.
// Diese verwalten die Speicherbereiche für die eigenen Elemente und stellen Member-Funktionen
// für den Zugriff und die Maniplulation bereit.
@ -876,7 +876,7 @@ for(it=ST.begin();it<ST.end();it++)
// 10
// 30
// Zum leeren des gesmten Container wird die Methode
// Zum leeren des gesamten Container wird die Methode
// Container._name.clear() verwendet.
ST.clear();
cout << ST.size(); // Ausgabe der Set-Größe
@ -918,7 +918,7 @@ cout << it->second;
// sind effizienter und benötigen keine Reihenfolge. "unordered_maps" sind ab
// C++11 verfügbar.
// Container für nicht-primitve Datentypen benötigen Vergleichsfunktionen im Objekt selbst,
// Container für nicht-primitive Datentypen benötigen Vergleichsfunktionen im Objekt selbst,
// oder als Funktionspointer. Primitive Datentypen besitzen default-Vergleichsfunktionen.
// Allerdings können diese überschrieben werden.
class Foo
@ -968,7 +968,7 @@ sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int,
// Beachte den Syntax von Lambda-Ausdrücken.
// Die [] im Lambda Ausdruck werden für die Variablen verwendet.
// Diese so genannte "Capture List" definiert, was außerhalb des Lambdas
// Diese so genannte "capture list" definiert, was außerhalb des Lambdas,
// innerhalb der Funktion verfügbar sein soll und in welcher Form.
// Dies kann folgendes sein:
// 1. ein Wert [x]
@ -1013,7 +1013,6 @@ for(int elem: arr)
}
// Insofern "auto" verwendet wird, muss der Typ nicht weiter beachtet werden.
for(auto elem: arr)
{
// Anweisungen ...
@ -1039,7 +1038,6 @@ class FooSub : public Foo
virtual void bar(); // Überschreibt Foo::bar!
};
// 0 == false == NULL
bool* pt = new bool;
*pt = 0; // Setzt den Wert des Pointers 'pt' auf false.
@ -1050,11 +1048,10 @@ int* pt2 = new int;
*pt2 = nullptr; // Kompiliert nicht.
pt2 = nullptr; // Setzt pt2 auf null.
// Eine Ausnahme bilden bools.
// Eine Ausnahme bilden bool´s.
// Dies erlaubt es "null-pointer" zu testen: if(!ptr)
// Die Konsequenz ist jedoch, dass dem nullptr ein bool zugewiesen werden kann.
*pt = nullptr; // Kompiliert auch wenn '*pt' ein bool ist!
*pt = nullptr; // Kompiliert auch, wenn '*pt' ein bool ist!
// '=' != '=' != '='!
// Ruft Foo::Foo(const Foo&) auf, oder den Kopierkonstruktor
@ -1077,8 +1074,8 @@ f1 = f2;
#include<tuple>
// Konzeptionell sind Tuples alten Datenstrukturen sehr ähnlich, allerdings haben diese keine
// benamten Daten-Member, sondern werden durch die Reihenfolge angesprochen.
// Konzeptionell sind Tuple´s alten Datenstrukturen sehr ähnlich, allerdings haben diese keine
// bezeichneten Daten-Member, sondern werden durch die Reihenfolge angesprochen.
// Erstellen des Tuples und das Einfügen eines Werts.
auto first = make_tuple(10, 'A');
@ -1122,8 +1119,7 @@ cout << get<5>(concatenated_tuple) << "\n"; // Ausgabe: 'A'
// Die meisten Operatoren in C++ entsprechen denen aus anderen Sprachen
// Logische Operatoren.
// C++ verwendet so genannte "Short-circuit" Evaluierung für boolean-Ausdrücke.
// C++ verwendet so genannte "Short-circuit" Evaluierung für Boolean-Ausdrücke.
// Das zweite Argument wird ausgeführt bzw. evaluiert, wenn das erste Argument genügt,
// um den Ausdruck zu bestimmen.