[[:improve]] CPlusPlus oder auch (C++) ist eine objektorientierte Programmiersprache. Siehe auch [[coding:c|C]]/[[coding:csharp|C#]]. [[https://en.cppreference.com/w/cpp/keyword|Cpp reference]] * explicit - makes a conversion constructor to non-conversion constructor. [[https://weblogs.asp.net/kennykerr/Explicit-Constructors|A good Write up]] * virtual - override class method * mutable - when you have a const class but want to change parts of it. =====Classes===== Klassen mit mindestens einer "virtual" Funktion nennt man Polymorphe Klassen. #include #include #include using namespace std; class Token { private: std::string type; std::string value; public: Token() { } Token(std::string _type, std::string _value) { type = _type; value = _value; } ~Token() { } std::string _value() { return value; } std::string _type() { return type; } std::string str() { if(type == "STRING") return ("Token(" + type + ", \"" + value + "\")"); else return ("Token(" + type + ", '" + value + "')"); } }; class ASTNode { public: std::vector child; Token token; ASTNode() { } ASTNode(Token _token) { token = _token; } ~ASTNode() { } void make_child(ASTNode _node) { ASTNode *temp = new ASTNode(_node._token()); temp->child = _node.child; child.push_back(temp); } Token _token() { return token; } void show(int level) { std::cout << std::string(level * 2, ' ') << token.str() << "\n"; for(auto it = child.begin(); it != child.end(); it++) (*it)->show(level + 1); } }; int main () { ASTNode ast = ASTNode(Token("STMT_LIST", "STMT_LIST")); ASTNode ass = ASTNode(Token("ASSIGN", "=")); ass.make_child(Token("VARIABLE", "f")); ass.make_child(Token("FLOAT", "3.14159")); ast.make_child(ass); ass = ASTNode(Token("ASSIGN", "=")); ass.make_child(Token("VARIABLE", "g")); ass.make_child(Token("FLOAT", "1.05")); ast.make_child(ass); ASTNode reass = ASTNode(Token("ASSIGN", "=")); reass.make_child(Token("VARIABLE", "fg")); ASTNode readd = ASTNode(Token("ADD", "+")); readd.make_child(Token("VARIABLE", "f")); readd.make_child(Token("VARIABLE", "g")); reass.make_child(readd); ast.make_child(reass); ast.show(0); return 0; } See also [[coding:c#classes|classes in c]] =====Local Classes===== void bar() { struct LocalClass { int operator()(int a, int b) const { return a + b; } } f; int n = f(1, 2); } =====Local Structs===== Pre C++11, ''localize'' a function to a function int foo () { struct Local { static int bar () { return 1; } }; return Local::bar(); } int foo (int x) { struct Local { int & x; Local (int & x) : x(x) {} int bar (int y) { return x * x + y; } }; return Local(x).bar(44); } =====Functor===== A functor is pretty much just a class which defines the operator(). That lets you create objects which "look like" a function: #include struct add_x { add_x(int val) : x(val) {} // Constructor int operator()(int y) const { return x + y; } private: int x; }; int main() { add_x add42(42); int i = add42(8); printf("%d", i); return 0; } =====Templates===== Templates werden mit dem Schlüsselwort "template" eingeleitet, gefolgt von der Template-Deklaration in spitzen Klammern ("<" und ">"). In der Template-Deklaration werden die Template-Parameter definiert, die den generischen Datentyp repräsentieren. #include template void swap(T& a, T& b) { T temp = a; a = b; b = temp; } template class Stack { private: T* data; int size; int capacity; public: Stack(int capacity) { this->capacity = capacity; this->size = 0; this->data = new T[capacity]; } void push(const T& element) { if (size < capacity) { data[size] = element; size++; } else { std::cout << "Stack is full. Cannot push element." << std::endl; } } T pop() { if (size > 0) { size--; return data[size]; } else { std::cout << "Stack is empty. Cannot pop element." << std::endl; return T(); // Return a default value for type T } } }; int main() { int a = 5, b = 10; swap(a, b); // Der Compiler generiert swap(a, b) double x = 2.5, y = 7.8; swap(x, y); // Der Compiler generiert swap(x, y) Stack intStack(10); intStack.push(1); intStack.push(2); intStack.push(3); int poppedIntElement = intStack.pop(); std::cout << "Popped element: " << poppedIntElement << std::endl; Stack doubleStack(10); doubleStack.push(1.2); doubleStack.push(2.4); doubleStack.push(3.14159); double poppedDoubleElement = doubleStack.pop(); std::cout << "Popped element: " << poppedDoubleElement << std::endl; return 0; } * [[http://www.cplusplus.com/doc/oldtutorial/templates/]] * [[https://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp|Codeproject article]] * http://www.willemer.de/informatik/cpp/cpptempl.htm * http://www.angelikalanger.com/Articles/Cuj/ExpressionTemplates/ExpressionTemplates.htm #include using namespace std; template void display(T1 x, T2 y); int main(){ display(1,2); display("Hello",3.14159); return 0; } template void display(T1 x, T2 y) { std::cout << x << " and " << y << "\n"; } #include using namespace std; template class Calculator{ public: Calculator(); TYPE Add(TYPE param1, TYPE param2); }; template Calculator::Calculator() {} template TYPE Calculator::Add(TYPE param1, TYPE param2) { cout << "Calculator::sum " << param1 << " " << param2 << endl; TYPE result = param1 + param2 ; return result; } int main(int argc, const char * argv[]) { Calculator calcI; cout << "outI : " << calcI.Add(65, 66) << "\n"; Calculator calcF; cout << "outF : " << calcF.Add(6.5, 6.6) << "\n"; Calculator calcS; cout << "outS : " << calcS.Add("A", "B") << "\n"; return 0; } You can fake templates in c using [[coding:c#preprocessing|preprocessing]] =====Closures===== void foo() { auto f = [](int a, int b) -> int { return a + b; }; auto n = f(1, 2); } =====Polymorphism===== Use keyword virtual to override class methods. [[https://www.youtube.com/watch?v=kxKKHKSMGIg|Youtube - c++ Polimorphism]] #include using namespace std; class Shape { protected: int width, height; public: Shape( int a = 0, int b = 0){ width = a; height = b; } virtual int area() { cout << "Shape area: "; return 0; } }; class Rectangle: public Shape { public: Rectangle( int a = 0, int b = 0):Shape(a, b) { } int area () { cout << "Rectangle area: "; return (width * height); } }; class Triangle: public Shape { public: Triangle( int a = 0, int b = 0):Shape(a, b) { } int area () { cout << "Triangle area: "; return (width * height / 2); } }; int main() { Shape *shape; Rectangle rec(13,5); Triangle tri(5,13); shape = &rec; std::cout << shape->area() << endl; shape = &tri; std::cout << shape->area() << endl; return 0; } =====Singletons===== #include using namespace std; class Singleton { public: static Singleton* getInstance() { if (m_instance == NULL) m_instance = new Singleton; return m_instance; } private: // private constructor and destructor Singleton() { cout << "Instance created!\n"; } ~Singleton() {} // private copy constructor and assignment operator Singleton(const Singleton&); Singleton& operator=(const Singleton&); static Singleton *m_instance; }; Singleton* Singleton::m_instance = nullptr; int main(int argc, const char * argv[]) { Singleton *singleton; singleton = singleton->getInstance(); cout << singleton << "\n"; Singleton *anotherSingleton; anotherSingleton = anotherSingleton->getInstance(); cout << anotherSingleton << "\n"; return 0; } =====Constants===== Das Schlüsselwort "const" (konstant) wird verwendet um zu definieren dass eine Variable oder ein Objekt nicht verändert werden kann. Ein Versuch den Wert zu ändern, führt zu einem Kompilierungsfehler. const int x = 5; x = 10; // Kompilierungsfehler: Assignment an eine konstante Variable nicht erlaubt Mit einer Konstanten kann man z.B auch die Länge eines Array zur Laufzeit definieren. const int arraySize = 10; int myArray[arraySize]; // Verwendung eines konstanten Ausdrucks für die Arraygröße See also [[coding:c#constants|constants in C]] =====Punning===== "Type punning" bezieht sich auf die Praxis, Speicherbereiche mit einer bestimmten Datentyp-Interpretation zu verwenden, die nicht dem ursprünglichen Typ entsprechen, um auf die darin enthaltenen Daten zuzugreifen. Ein klassisches Beispiel ist die Manipulation von Bits innerhalb eines Integers, um spezielle Flags oder Optionen zu setzen oder zu überprüfen. unsigned int options = 0; options |= (1 << 2); // Set the third bit to 1 options &= ~(1 << 0); // Clear the first bit * Pointer conversion * union * reinterpret_cast Type punning wird nicht als "good practice" angesehen weil Datentypen auf verschiedene Weisen von Systemen interpretiert werden können.. =====Casting===== =====Links===== [[https://www.heise.de/developer/artikel/C-20-Die-vier-grossen-Neuerungen-4568956.html|C++ 20 Neuerungen]]