48
C++11 Defaulted & Deleted Functions http://www.wilkening-online.de 1 / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening http://www.wilkening-online.de 8.5.2014 & 14.8.2014

C++11 Defaulted & Deleted Functions / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

Embed Size (px)

Citation preview

Page 1: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 1 / 48

C++11Defaulted & Deleted Functions

Detlef Wilkeninghttp://www.wilkening-online.de8.5.2014 & 14.8.2014

Page 2: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 2 / 48

Themen: 6 spezielle Funktionen in Klassen und ihre Erzeugungs-Regeln Explicitly Defaulted Functions Deleted Functions ISO & Links

Page 3: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 3 / 48

6 spezielle Member-Funktionen

in Klassen und ihre Erzeugungs-Regeln

Page 4: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 4 / 48

Spezielle Member-Funktionen einer Klasse "A"• Standard-Konstruktor A()• Destruktor ~A()• Kopier-Konstruktor A(const A&)• Kopier-Zuweisungs-Operator A& operator=(const A&)• Move-Konstruktor A(A&&)• Move-Zuweisungs-Operator A& operator=(A&&)

Page 5: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 5 / 48

Standard-Konstruktor: A()• Der implizite Standard-Konstruktor wird nur dann erzeugt,

wenn kein anderer Konstruktor explizit deklariert wurde, undwenn er erzeugbar ist

Page 6: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 6 / 48

Destruktor: ~A()• Der implizite Destruktor wird immer erzeugt,

außer es gibt einen user-deklarierten Destruktor, oder er ist nicht erzeugbar.

Page 7: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 7 / 48

Kopier-Konstruktor: A(const A&)• Der implizite Kopier-Konstruktor wird erzeugt, wenn:

• er nicht explizit deklariert wurde,• er generierbar ist, d.h. alle Elemente der Klasse kopierbar sind,• es keinen expliziten Move-Konstruktor gibt (C++11), und• es keinen expliziten Move-Zuweisungs-Operator gibt (C++11)

• Zusätzlich in C++11:• Wenn der Destruktor oder der Kopier-Zuweisungs-Operator explizit deklariert

wurde, dann ist die Erzeugung des Kopier-Konstruktors deprecated.

Kopier-Zuweisungs-Operator: A& operator=(const A&)• Der implizite Kopier-Zuweisungs-Operator wird erzeugt, wenn:

• er nicht explizit deklariert wurde,• er generierbar ist, d.h. alle Elemente der Klasse kopier-zuweisbar sind,• es keinen expliziten Move-Konstruktor gibt (C++11), und• es keinen expliziten Move-Zuweisungs-Operator gibt (C++11)

• Zusätzlich in C++11:• Wenn der Destruktor oder der Kopier-Konstruktor explizit deklariert wurde,

dann ist die Erzeugung des Kopier-Zuweisungs-Operators deprecated.

Page 8: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 8 / 48

Move-Konstruktor: A(A&&)• Der implizite Move-Konstruktor wird erzeugt, wenn:

• er nicht explizit deklariert wurde,• kein expliziter Kopier-Konstruktor deklariert wurde,• kein expliziter Kopier-Zuweisungs-Operator deklariert wurde,• kein expliziter Move-Zuweisungs-Operator deklariert wurde,• kein expliziter Destruktor deklariert wurde, und• er generierbar ist

D.h. wenn alle Elemente der Klasse "movebar" sind

Move-Zuweisungs-Operator: A& operator=(A&&)• Der implizite Move-Zuweisungs-Operator wird erzeugt, wenn:

• er nicht explizit deklariert wurde,• kein expliziter Kopier-Konstruktor deklariert wurde,• kein expliziter Kopier-Zuweisungs-Operator deklariert wurde,• kein expliziter Move-Konstruktor deklariert wurde,• kein expliziter Destruktor deklariert wurde, und• er generierbar ist

D.h. wenn alle Elemente der Klasse "move-zuweisbar" sind

Page 9: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 9 / 48

C++ 11 erlaubt eine exakte Steuerung der Generierung dieser6 speziellen Member-Funktionen• Dafür gibt es in C++11 nun die Möglichkeit mit "=default" oder "=delete" die

Generierung zu aktivieren oder zu verbieten• Siehe ISO/IEC 14882, Kapitel 12.1, 12.4, 12.7, 12.8 und 13.5.3

Page 10: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 10 / 48

Explicitly Defaulted Functions

Page 11: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 11 / 48

Explicitly-defaulted Functions• So nennt der Standard sie: ISO/IEC 14882:2011(E) § 8.4.2• Bezieht sich nur auf die speziellen Member-Funktionen

• Nur: Standard-Konstruktor A() Destruktor ~A() Kopier-Konstruktor A(const A&) Kopier-Zuweisungs-Operator A& operator=(const A&) Move-Konstruktor A(A&&) Move-Zuweisungs-Operator A& operator=(A&&)

• Denn diese könnten nicht erzeugt werdenBzw. werden speziell benötigt (z.B. virtueller Destruktor)

Page 12: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 12 / 48

Wird eine der speziellen Member-Funktionen nicht erzeugt, so kann man die Erzeugung erzwingen• = default hinter die Funktions-Deklaration

class A

{

public: A() = default; ~A() = default; A(const A&) = default; A& operator=(const A&) = default; A(A&&) = default; A& operator=(A&&) = default;

};

Page 13: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 13 / 48

Haupt-Anwendung:• Erzeugungs-Regeln verhindern die automatische Erzeugung• Funktion soll trotzdem vorhanden sein• Achtung

• Auch "explizit defaulted Funktionen" sind user-deklarierte Funktionenund greifen daher in die Erzeugungs-Regeln ein

class A

{

public: A() = default; // Soll normal da sein A(int); // Verhindert Erzeugung vom Standard-Konstruktor

private: std::string s;

};

Page 14: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 14 / 48

Weitere Anwendungen• Veränderung des Zugriffs-Bereichs• Virtueller Destruktor• Trivialer Typ

Page 15: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 15 / 48

Veränderung des Zugriffs-Bereichs• Beispiel

• Standard-Konstruktor wäre vorhanden• Aber public – soll protected sein• Möglich mit = default

class A

{

public:

virtual ~A();

protected: A() = default; // Soll normal da sein, aber protected

private: std::string s;

};

Page 16: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 16 / 48

Virtueller Destruktor• Basis-Klassen sollten einen virtuellen Destruktor haben• Mußte früher häufig explizit leer implementiert werden• Heute einfach mit = default

class A

{

public:

virtual ~A() = default; // Normal vorhanden, aber virtual

};

Page 17: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 17 / 48

Trivialer Typ• Eine Klasse mit z.B. einem expliziten Standard-Konstruktor ist nicht trivial

• Kein POD – „Plain Old Data“• =>

• Compiler kann nicht beliebig optimieren• Funktionen dürfen nicht übersprungen werden• Storage darf nicht wiederverwendet werden• memcpy kann nicht verwendet werden• Type-Trait Optimierungen für PODs greifen nicht

• => • Trivialer Typ ist häufig erstrebenswert

Wichtig• Alle Funktionen werden mit „= default“ so erzeugt,

wie die automatisch generierten Funktionen erzeugt worden wären.

Page 18: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 18 / 48

Typ ist trotz lauter expliziter spezieller Funktionen ein POD

struct Trivial

{

Trivial() = default;

Trivial(const Trivial&) = default;

Trivial(Trivial&&) = default;

Trivial& operator=(const Trivial&) = default;

Trivial& operator=(Trivial&&) = default;

~Trivial() = default;

};

Page 19: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 19 / 48

Besonderheiten bei „explicitly defaulted functions“:• Variationen der speziellen Funktionen• constexpr• Default ausserhalb der Klassen-Definition

Page 20: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 20 / 48

Variationen der speziellen Funktionen• Bei der Deklaration der speziellen Funktionen mit „= default“ sind nur

minimale Variationen erlaubt• Kopier-Konstruktor, Kopier-Zuweisungs-Operator, Move-Konstruktor und Move-

Zuweisungs-Operator dürfen auch non-const und/oder volatile Referenzen haben• Der Rückgabe-Typ der Zuweisungs-Operatoren ist nicht frei• Exception-Spezifikation muß matchen

• Parameter mit Default-Argumenten sind weder beim Standard-Konstruktor, Kopier-Konstruktor noch Move-Konstruktor mit „= default“ erlaubt

class A

{

public:

A(int=0) = default; // Fehler – Default-Argument

~A() throw(int) = default; // Fehler – Exceptions-Sp.

void operator=(A&&) = default; // Fehler - Rückgabe-Typ

A(A&) = default; // Okay, auch non-const Referenz

};

Page 21: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 21 / 48

constexpr• Eine explizit defaulted Funktion kann nur „constexpr“ sein,

wenn es auch die normale automatische Funktion wäre

struct A

{

constexpr A() = default; // Fehler - constexpr

private:

int i;

};

Page 22: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 22 / 48

Default ausserhalb der Klassen-Definition• Spezielle Funktionen können auch ausserhalb der Klassen-Definition explizit

defaulted werden• Achtung – solche Klassen sind dann niemals triviale Typen

• Denn unterschiedliche Nutzungs-Stellen könnten unterschiedliche Definitionen sehen

struct NonTrivial

{

NonTrivial();

};

NonTrivial:: NonTrivial() = default; // Okay

// Aber nicht trivial

Page 23: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 23 / 48

Fazit• Sie können alle automatisch generierbaren speziellen Member-Funktionen

(ohne new & delete) in C++11 explizit default machen• Sie werden dann „normal“ generiert

• Daher triviale Typen bleiben triviale Typen• Damit können

• Unterdrückte automatische Generierungen wieder aktiviert werden• Zugriffsbereiche verändert werden• Virtuelle Destruktoren vereinfacht werden• Typen trivial gehalten werden

Page 24: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 24 / 48

Deleted Functions

Page 25: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 25 / 48

"= delete" hinter einer Funktion löscht diese Funktion• Damit kann man die Generierung von speziellen Funktionen unterdrücken

Haupt-Anwendung• Verbieten, dass ein Typ kopierbar und/oder movebar ist

Page 26: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 26 / 48

Klassen sollten die Regel der 3, 4, 5, 6 oder 0 erfüllen Regel-der-3 - C++03

• Wenn eine Klasse einen expliziten Destruktor, Kopier-Konstruktor oder Kopier-Zuweisungs-Operator hat, dann ist es extrem wahrscheinlich das auch die anderen beiden speziellen Funktionen explizit definiert werden müssen.

Regel-der-4 - besseres C++03• Ohne eine typ-spezifische Swap-Funktion kann man den Kopier-Konstruktor

nur schwer sinnvoll und exception-sicher implementieren• Copy&Swap Idiom

Regel-der-5 - C++11• Regel-der-3 zusätzlich mit Move-Konstruktor und Move-Zuweisungs-Operator

Regel-der-6 - besseres C++11• Typ-spezifische Swap-Funktion ist ein Stück performanter als Swap mit Move

Regel-der-0 - C++11• Man nutzt RAII Klassen und benötigt keine spezielle Member-Funktion

Page 27: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 27 / 48

Problem• Typ hat expliziten Destruktor, und die implizite Funktionen wie z.B. Kopier-

Konstruktor funktionieren nicht korrekt

Lösungen in C++03• Kopier-Konstruktor und -Zuweisungs-Operator privat deklarieren,

aber nicht implementieren• Beispiel siehe nächste Folie

• Klasse privat ableiten von boost::noncopyable• Beispiel siehe nächste Folie

Page 28: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 28 / 48

class NonCopyable : boost::noncopyable // Achtung - kein POD

{

public:

// Impliziter Standard-Konstruktor ist auch nicht trivial

};

class NonCopyable // Achtung - kein POD

{

public:

NonCopyable() {} // Achtung - nicht trivial

private:

NonCopyable(const NonCopyable&); // ohne Impl.

NonCopyable& operator=(const NonCopyable&); // ohne Impl.

};

Page 29: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 29 / 48

Nachteile• Standard-Konstruktor muß möglicherweise explizit gemacht werden

=> Standard-Konstruktor ist nicht trivial => kein POD• Friends und Member-Funktionen haben immer noch Zugriff

=> erst Linker-Fehler schlägt zu• Die Intention ist schwer zu verstehen

• Obwohl es ein akzeptiertes und verbreitetes Idiom ist

Page 30: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 30 / 48

Lösung in C++11• Funktion mit "= delete" entfernen

class NonCopyable // Ist POD

{

public:

NonCopyable() = default; // Ist trivial

NonCopyable(const NonCopyable&) = delete;

NonCopyable& operator=(const NonCopyable&) = delete;

};

Page 31: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 31 / 48

Vorteile• Standard-Konstruktor ist durch "= default" weiterhin trivial

=> Klasse kann also ein POD sein• Trotz Public-Funktionen gibt es beim Kopieren und Kopier-Zuweisen

immer einen Compiler-Fehler• Denn die Funktionen sind "deleted"

• Die Intention ist sofort klar

Hinweis• Der Typ "NonCopyable" ist auch nicht movebar• Denn die explizite Deklaration von z.B. dem Kopier-Konstruktor reicht

• Move-Konstruktor und -Zuweisungs-Operator werden nicht implizit erzeugt

Page 32: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 32 / 48

Will man Typ haben, der movebar aber nicht kopierbar ist• Wie z.B. beim C++11 "std::unique_ptr"• Kopier-Operationen "deleten"• Move-Operationen "defaulten"

class OnlyMoveable

{

public:

OnlyMoveable() = default;

OnlyMoveable(const OnlyMoveable&) = delete;

OnlyMoveable& operator=(const OnlyMoveable&) = delete;

OnlyMoveable(OnlyMoveable&&) = default;

OnlyMoveable& operator=(OnlyMoveable&&) = default;

};

Page 33: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 33 / 48

Aber es gibt auch noch andere Anwendungsfälle für = delete Z.B. eine Klasse, die nicht erzeugbar und zerstörbar ist

• Vielleicht als Sammlung von statischen Funktionen• Oder warum auch immer

=>• Standard-Konstruktor deleten• Optional auch noch deleten des Destruktors

• Aber eigentlich nicht notwändig

class A

{

public:

A() = delete;

~A() = delete;

};

Page 34: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 34 / 48

Man kann nicht nur die speziellen Member-Funktionen deleten• Das geht auch für andere generierte Funktionen

• New & Delete Operatoren• Ganz normale Funktionen• Template-Funktionen

Page 35: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 35 / 48

Deleten von New & Delete Operatoren• Typ läßt sich nicht dynamisch erstellen• Achtung - alle impliziten New-Varianten deleten (wenn gewollt)• "delete" muß nicht deleted werden - könnte man aber machen

class Type

{

public:

static void* operator new(std::size_t) = delete;

static void* operator new[](std::size_t) = delete;

static void* operator new(size_t, const nothrow_t&) noexcept = delete;

static void* operator new[](size_t, const nothrow_t&) noexcept = delete;

};

Type* p = new Type; // Compiler-Fehler

Type* q = new Type[4]; // Compiler-Fehler

Page 36: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 36 / 48

Ganz normale Funktionen• Aber man kann auch ganz normale Funktionen deleten• Dann werden z.B. beim Überladen die entsprechenden Konvertierungen

unterbunden

void f(double);

void f(int) = delete;

f(3.14); // Okay

f(3); // Compiler-Fehler

// -> Exakt passende Funktion mit "int" ist "deleted"

// => keine Propagation zu "double"

Page 37: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 37 / 48

Die normale Typ-Propagation ist dadurch nicht unterbunden• Double-Variante vorhanden• delete auf Float-Variante• =>

• Propagation auf double, die der float nicht abfängt, werden natürlich weiterhin durchgeführt

• Mit Templates läßt sich das verallgemeinern => siehe nächsten Folien

void f(double);

void f(float) = delete;

f(3.14); // Okay

f(3.14f); // Compiler-Fehler

f(3); // Okay - Propagation zu double

Page 38: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 38 / 48

Variation mit Template-Funktion• Normale Funktion deleten• Template-Funktion anbieten

=>• Nun geht jeder Typ außer dem deleteten

• Natürlich mit der Template-Funktion

void f(double) = delete;

template<class T> void f(T) {}

f(3); // Okay

f("C++"s); // Okay

f(3.14); // Compiler-Fehler

Page 39: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 39 / 48

Template-Funktionen• Erstellt man eine Template-Funktion und deleted sie, und überlädt sie mit

einer konkreten Funktion, so kann man die Funktion nur mit dem exakten Typ aufrufen

• Denn alle anderen Typen würden auf die Template-Funktion zurückgreifen, und die ist deleted.

void f(double);

template<class T> void f(T) = delete;

f(3.14); // Okay

f("C++"s); // Compiler-Fehler

f(3); // Compiler-Fehler

Page 40: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 40 / 48

Besonderheiten bei Deleted Funktionen• Redundante deletes sind erlaubt• Deleted Funktionen sind implizit inline• Deleted Funktionen dürfen natürlich nicht nochmal definiert werden

Page 41: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 41 / 48

Redundante deletes sind erlaubt• Daher deletes, die eigentlich nicht notwändig sind• Z.B. Standard-Konstruktor explizit deleten, obwohl anderer Konstruktor da ist

• Der implizite wird dann ja nicht erzeugt

class Type

{

public:

Type() = delete; // Redundant, aber okay

Type(int);

};

Page 42: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 42 / 48

Deleted Funktionen sind implizit inline• Daher "= delete" muß in der Klassen-Definition stehen• Bei der "ersten Deklaration"• Sonst wäre es eine Verletzung der ODR

class Type

{

public:

Type();

};

Type::Type() = delete; // Compiler-Fehler

Page 43: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 43 / 48

Deleted Funktionen dürfen nicht nochmal definiert werden• "= delete" entspricht einer Defintion• Würde anders ja auch keinen Sinn machen• Also anders als z.B. bei rein virtuellen Funktionen mit = 0

void fct(long) = delete;

void fct(long) { } // Compiler-Fehler

Page 44: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 44 / 48

Fazit• Sie können alle Arten von Funktionen in C++11 deleten• Typischerweise wird dies für die speziellen Member-Funktionen gemacht

• Um Klassen nicht-kopierbar und/oder nicht moveable und/oder nicht dynamisch erzeugbar zu machen

• Außerdem kann man damit auch:• Überladungs-Fehler einschränken• Parameter-Propagationen verhindern• Template-Instanziierungen steuern

Page 45: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 45 / 48

ISO & Links

Page 46: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 46 / 48

C++11 Standard - ISO/IEC 14882• 8.4 Function definitions

• 8.4.1 In general• 8.4.2 Explicitly-defaulted functions• 8.4.3 Deleted definitions

• 12 Special member functions• 12.1 Constructors• 12.4 Destructors• 12.7 Construction and destruction• 12.8 Copying and moving class objects

• 13 Overloading• 13.5 Overloaded operators

13.5.3 Assignment

Page 47: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 47 / 48

Links• http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2210.html • http://en.wikipedia.org/wiki/C%2B

%2B11#Explicitly_defaulted_and_deleted_special_member_functions • http://www.stroustrup.com/C++11FAQ.html#default• https://www.ibm.com/developerworks/community/blogs/5894415f-be62-

4bc0-81c5-3956e82276f3/entry/defaulted_functions_in_c_11?lang=en • http://msdn.microsoft.com/en-us/library/dn457344.aspx• http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=353• http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=354

Page 48: C++11 Defaulted & Deleted Functions  / 48 C++11 Defaulted & Deleted Functions Detlef Wilkening

C++11 Defaulted & Deleted Functions

http://www.wilkening-online.de 48 / 48

Danke