Listings Wilkening/Idiome

Listing 1: Implementieren mit Prä- und Post-Inkrement-Operator
class MyInt
{
public:
    MyInt(int v=0) : value(v) {}

    MyInt& operator++()    // Prä-Inkrement-Operator
    {
      ++value;
      return *this;
    }

    MyInt operator++(int)    // Post-Inkrement-Operator
    {
      MyInt cpy(*this);
      ++value;
      return cpy;
    }

private:
    int value;
};

-----

Listing 2: Scoped Enums erfordern qualifizierte Namen
enum class Color { red, blue };    // Scoped Enum

void fct()
{
    Color c = Color::red;    // Qualifizierter Name notwendig
    if (c == Color::blue)     // Qualifizierter Name notwendig
    {
      ...
    }
}

-----

Listing 3: Simulation von qualifizierten Namen mit Namespace
namespace Color
{
    enum Enum { red, blue };    // Unscoped Enum
}

void fct()
{
    Color::Enum c = Color::red;    // Qualifizierung durch Namespace-Namen
    if (c == Color::blue)          // Qualifizierung durch Namespace-Namen
    {
      ...
    }
}

-----

Listing 4: Using-Deklaration für einen simulierten Scoped Enum
namespace Color
{
    enum Enum { red, blue };
}

void fct()
{
    using Color::red;      // Using-Deklaration
    Color::Enum c = red;   // Keine Qualifizierung notwendig
    if (c == Color::blue)
    {
      //...
    }
}

-----

Listing 5: Using-Deklaration für Enums in C++20
enum class Color { red, blue };    // Scoped Enum

void fct()
{
    using enum Color;    // C++20
    Color c = red;       // Keine Qualifizierung notwendig
    if (c == blue)       // Keine Qualifizierung notwendig
    {
      ...
    }
}

-----

Listing 6: Automatische Vergleichsoperatoren durch Boost.Operator
struct MyInt : boost::totally_ordered<MyInt>
{
    explicit MyInt(int v=0) : value(v) {}
    bool operator==(const MyInt& arg) const { return value==arg.value; }
    bool operator< (const MyInt& arg) const { return value<arg.value; }
private:
    int value;
};

-----

Listing 7: Attribute vergleichen
class date
{
    int year;
    int month;
    int day;
    ...
};

bool date::operator<(const date& d) const
{
    if (year<d.year) return true;
    if (year>d.year) return false;
    if (month<d.month) return true;
    if (month>d.month) return false;
    return day<d.day;
}

-----

Listing 8: Der Spaceship-Operator liefert alle Vergleichsoperatoren
class date
{
public:
    auto operator<=>(const date&) const = default;  // C++20: Automatischer Spaceship-Operator
    ...                                             // => Alle Vergleichsoperatoren vorhanden
private:
    int year;
    int month;
    int day;
};

-----

Listing 9: Explizite Angabe der Basisklasse
struct A
{
    A(int);
    virtual void fct() const;
};

struct B : A
{
    B(int x) : A(x) {}  // Angabe der Basisklasse "A"

    void fct() const override
    {
      A::fct();         // Angabe der Basisklasse "A"
    }
};

-----

Listing 10: Typalias für super
struct A
{
    A(int);
    virtual void fct() const;
};

struct B : A
{
    using super = A;          // Typalias fuer "A"
    B(int x) : super(x) {}    // Angabe von "super"

    void fct() const override
    {
      super::fct();           // Angabe von "super"
    }
};

-----

Listing 11: Basisklassenfunktion und überschreibende Funktion
struct A
{
    virtual void fct() const
    {
      ...
    }
};

struct B : A
{
    void fct() const override
    {
      ...
    }
};

-----

Listing 12: Ein- und Ausstiegspunkte für virtuelle Funktionen
struct A
{
    void fct() 
    {    // << Einstiegspunkt
      execute_fct(); 
    }    // << Ausstiegspunkt

protected:
    virtual void execute_fct() const
    {
      ...
    }
};

struct B : A
{
protected:
    void execute_fct() const override
    {
      ...
    }
};

-----

Listing 13: before- und after-Methoden für virtuelle Funktionen
struct A
{
    void fct()
    {
      if (execute_fct_before())
        execute_fct(); 
      execute_fct_after();
    }

protected:
    virtual bool execute_fct_before() { return true; }
    virtual void execute_fct_after() { }

    virtual void execute_fct() const
    {
      ...
    }
};

-----

Listing 14: Rein virtuelle Funktionen dürfen private sein
struct A
{
    void fct() { execute_fct(); }

private:                                     // Nur privater Zugriff
    virtual void execute_fct() const = 0;    // Rein virtuelle Funktion
};
