-
Notifications
You must be signed in to change notification settings - Fork 0
01 Cpp Grundlagen
C++ wurde 1979 von Bjarne Stroustrup als "C with Classes" entwickelt, um objektorientierte Konzepte in C zu integrieren. 1983 wurde der Name in C++ geändert, und viele neue Funktionen wurden hinzugefügt. Zwischen 1990 und 1998 kamen Templates, Ausnahmen, Namensräume und die Standard Template Library (STL) hinzu. Die Normierung erfolgte 1998 (ISO/IEC 14882:1998).
-
C++11 führte viele neue Funktionen ein, darunter Move-Semantik, Smart Pointer, Lambdas und Typinferenz.
Beispiel für eine Lambda-Funktion:auto add = [](int a, int b) { return a + b; }; std::cout << add(3, 4) << std::endl; // Ausgabe: 7
Beispiel für Smart Pointer:
#include <memory> std::unique_ptr<int> p = std::make_unique<int>(10); std::cout << *p << std::endl; // Ausgabe: 10
-
C++14 brachte Verbesserungen wie generische Lambda-Ausdrücke und benutzerdefinierte Literale.
Beispiel für generische Lambda:auto multiply = [](auto a, auto b) { return a * b; }; std::cout << multiply(3, 4.5) << std::endl; // Ausgabe: 13.5
-
C++17 führte u. a. parallele Algorithmen,
std::variantundstd::optionalein.
Beispiel fürstd::optional:#include <optional> std::optional<int> getValue(bool flag) { if (flag) { return 42; } return std::nullopt; } auto value = getValue(true); if (value) { std::cout << "Wert: " << *value << std::endl; // Ausgabe: Wert: 42 }
-
C++20 fügte Konzepte, Module, Coroutinen und eine Ranges-Bibliothek hinzu.
Beispiel für Coroutinen:#include <coroutine> #include <iostream> struct Generator { struct promise_type { int current_value; std::suspend_always yield_value(int value) { current_value = value; return {}; } Generator get_return_object() { return Generator{this}; } std::suspend_always initial_suspend() { return {}; } std::suspend_never final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception() { std::terminate(); } }; promise_type* promise; Generator(promise_type* p) : promise(p) {} struct iterator { promise_type* promise; bool operator!=(std::default_sentinel_t) const { return true; } void operator++() { promise->current_value++; } int operator*() const { return promise->current_value; } }; iterator begin() { return iterator{promise}; } std::default_sentinel_t end() { return {}; } }; Generator counter() { for (int i = 0; i < 5; ++i) { co_yield i; } } int main() { for (auto value : counter()) { std::cout << value << " "; // Ausgabe: 0 1 2 3 4 } }
Neue Funktionen umfassen Erweiterungen der Ranges-Bibliothek (views::chunk,
views::zip), std::expected, Monadic Interfaces und Attribute für Lambdas.
Klassen bestehen typischerweise aus einer Schnittstellendatei (Header) und einer
Implementierungsdatei. Header-only-Bibliotheken enthalten den gesamten Code in
Header-Dateien.
Beispiel für eine einfache Klassendeklaration und Implementierung:
// Header-Datei (Person.h)
#ifndef PERSON_H
#define PERSON_H
#include <string>
class Person {
private:
std::string name;
int age;
public:
Person(const std::string& name, int age);
void print() const;
};
#endif
// Implementierungsdatei (Person.cpp)
#include "Person.h"
#include <iostream>
Person::Person(const std::string& name, int age) : name(name), age(age) {}
void Person::print() const {
std::cout << "Name: " << name << ", Age: " << age << std::endl;
}
// Nutzung der Klasse
#include "Person.h"
int main() {
Person p("Alice", 30);
p.print(); // Ausgabe: Name: Alice, Age: 30
return 0;
}Es gibt zwei Arten von Klassen: struct für öffentliche Mitglieder und class
für private Mitglieder. Methoden werden in den Implementierungsdateien
definiert.
Das Schlüsselwort auto ermöglicht es, den Datentyp einer Variablen automatisch
vom Initialisierungswert abzuleiten. decltype gibt den Deklarationstyp eines
Ausdrucks zurück.
Beispiel:
auto x = 7;
double f();
auto g = f();
decltype(g) h = 5.5;Das Schlüsselwort constexpr ermöglicht es, konstante Ausdrücke und Funktionen
zur Kompilationszeit zu berechnen. Es wird verwendet, um konstante Werte
effizienter zu definieren.
Beispiel:
constexpr int square(int x) {
return x * x;
}
constexpr int value = square(5); // Wert wird zur Kompilationszeit berechnetMit Initialisierungslisten können mehrere Werte einfach an Konstruktoren
übergeben werden. Die vereinheitlichte Initialisierung ({}) bietet eine
einheitliche Syntax zur Initialisierung von Objekten.
Beispiel:
struct Point {
int x, y;
};
Point p1{1, 2}; // vereinheitlichte Initialisierung
std::vector<int> vec = {1, 2, 3, 4};Referenzen (&) sind Aliasse für Variablen und ermöglichen eine effiziente
Parameterübergabe ohne Datenkopie. Objekte können by Value, by Reference oder by
Pointer an Funktionen übergeben werden.
Beispiel:
void increment(int& n) {
++n;
}
int main() {
int value = 5;
increment(value);
std::cout << value << std::endl; // Ausgabe: 6
}C++ bietet verschiedene Methoden zur Typkonvertierung:
-
static_cast: Normale Typkonvertierungdouble d = 3.14; int i = static_cast<int>(d); // Konvertiert d zu einem int
-
dynamic_cast: Down-Casting in Klassenhierarchienclass Base { virtual void foo() {} }; class Derived : public Base {}; Base* b = new Derived; Derived* d = dynamic_cast<Derived*>(b);
-
const_cast: Entfernt oder fügtconsthinzuconst int a = 10; int& b = const_cast<int&>(a); b = 20;
-
reinterpret_cast: Konvertierung ohne Compiler-Überprüfungint a = 65; char c = reinterpret_cast<char&>(a); // Konvertiert int zu char
Diese Zusammenfassung bietet eine grundlegende Einführung in C++, beginnend bei der Geschichte der Sprache bis hin zu den neuesten Entwicklungen im modernen C++. Sie beleuchtet die wichtigsten Sprachfunktionen und deren Verwendung zur Entwicklung von Klassen und effizienten Programmen.