Cpp 11 - GameEngineKoblenz/GeKo GitHub Wiki

auto

Renderer create_renderer(){
  ...
}

Renderer r = create_renderer();

auto r = create_renderer();

Erklärung:

Anstatt einen Typ für das Objekt "r" explizit anzugeben, kann man "auto" verwenden. "auto" wird automatisch zur Compile-Zeit mit dem richtigen Typ ersetzt.

unique_ptr

 //c++98 DO NOT WRITE THIS
 Foo *f = new Foo(1,"Hello");
 
 //c++11
 std::unique_ptr f(new Foo(1,Hello);

 //c++14
 auto f = make_unqiue<Foo>(1,"Hello");

Erklärung:

  1. "new Foo(...)" erzeugt ein Objekt auf dem Heap. Kleine Objekte sollten jedoch besser auf dem Stack liegen und mit "Foo f(1, "Hello")" erzeugt werden.

Der Stack ist schnell & begrenzt, der Heap ist "unbegrenzt" & langsam.

  1. "unique_ptr" und "make_unique" erlaubt, bei Verwendung, nur maximal einen Zeiger auf das entsprechende Objekt.

For

//Note prefer std::array< over type[]

std::array<int,5> arr ={1,2,3,4,5};
for(int& e : arr) 
{
  e = e*e;
}

Erklärung:

1.) "array<int, 5>" gibt dem Array einen Typ ("int") und eine Größe ("5") vor.

2.) Die for-Schleife iteriert über das Array und quadriert die beinhalteten Werte

override/final

class B 
{
public:
   virtual void f(int) {std::cout << "B::f" << std::endl;}
};

class D : public B
{
public:
   virtual void f(int) override final {std::cout << "D::f" << std::endl;}
};

class F : public D
{
public:
   virtual void f(int) override {std::cout << "F::f" << std::endl;}
};

Erklärung:

1.) Wenn alle Methoden in einer Klasse "virtual" sind, handelt es sich um ein Interface (siehe "class B").

2.) "override" gibt vor, dass die entsprechende Methode bereits in einem Interface vorhanden sein muss.

3.) "final" signalisiert, dass nach dieser Implementierung, die entsprechende Methode nicht mehr als virtual gilt.

Move

std::vector<unique_ptr<Foo>> v;
std::unique_ptr f(new Foo());

v.push_back(f); // does NOT compile
v.push_back(std::move(f));

Erklärung:

Mit der Methode "move(f)" wird der Zeiger nicht kopiert, sondern übergeben. Dies bedeutet also, dass der "Besitzer" des Zeigers wechselt.

Using

using my_vec = std::vector<std::vector<float>>;

// v1 and v2 have the same type
my_vec v1;
std::vector<std::vector<float>> v2;

my_vec some_function(const my_vec &v){...}
std::vector<std::vector<float>> some_function(const std::vector<std::vector<float>> &v){...}

Erklärung:

Mit "using" kann ein Typ, wie beispielsweise "std::vector<std::vector>" (s.o.), durch eine eigene Typbezeichnung, beispielsweise "my_vec" (s.o.), ersetzt werden. "my_vec" wird zur Compile-Zeit an den entsprechenden Stellen durch den ursprünglichen Typ ersetzt.

Static assert

// Build error
static_assert( 1 < 2, "1 is not bigger than 2");

//Example
template <typename T, size_t Size>
class Vector
{
   static_assert(Size < 3, "Size is too small");
   T _points[Size];
};

int main()
{
   Vector<int, 16> a1;
   Vector<double, 2> a2; // Doesn't compile
   return 0;
} 

Erklärung:

Die Asserts funktionieren vom Prinzip her wie in Java. Jedoch wirft "static_assert(Size < 3, "Size is to small")" die Fehlermeldung ("Size is to small"), wenn die Bedingung ("Size < 3") true ist.

⚠️ **GitHub.com Fallback** ⚠️