c++ interface - Wie deklariert man eine Schnittstelle in C ++?





constructor beispiel (13)


Ich bin noch neu in C ++ Entwicklung. Ich habe mit Visual Studio (VS) angefangen.

Dennoch scheint niemand die __interface in VS (.NET) zu erwähnen. Ich bin nicht sehr sicher, ob dies eine gute Möglichkeit ist, eine Schnittstelle zu deklarieren. Aber es scheint eine zusätzliche Durchsetzung (in den Dokumenten erwähnt ) zu bieten. So dass Sie die virtual TYPE Method() = 0; nicht explizit angeben müssen virtual TYPE Method() = 0; , da es automatisch konvertiert wird.

__interface IMyInterface {
   HRESULT CommitX();
   HRESULT get_X(BSTR* pbstrName);
};

Allerdings benutze ich es nicht, da ich Bedenken wegen der plattformübergreifenden Kompilierungskompatibilität habe, da es nur unter .NET verfügbar ist.

Wenn jemand etwas Interessantes daran hat, bitte teilen. :-)

Vielen Dank.

Wie richte ich eine Klasse ein, die eine Schnittstelle darstellt? Ist das nur eine abstrakte Basisklasse?




Es gibt kein Konzept von "Schnittstelle" per se in C ++. AFAIK, Schnittstellen wurden erstmals in Java eingeführt, um den Mangel an Mehrfachvererbung zu umgehen. Dieses Konzept hat sich als sehr nützlich erwiesen, und der gleiche Effekt kann in C ++ durch Verwendung einer abstrakten Basisklasse erreicht werden.

Eine abstrakte Basisklasse ist eine Klasse, in der mindestens eine Elementfunktion (Methode in Java-Jargon) eine reine virtuelle Funktion ist, die mit folgender Syntax deklariert wird:

class A
{
  virtual void foo() = 0;
};

Eine abstrakte Basisklasse kann nicht instanziiert werden, dh Sie können kein Objekt der Klasse A deklarieren. Sie können nur Klassen von A ableiten, aber jede abgeleitete Klasse, die keine Implementierung von foo() bereitstellt, wird ebenfalls abstrakt sein. Um nicht mehr abstrakt zu sein, muss eine abgeleitete Klasse Implementierungen für alle reinen virtuellen Funktionen bereitstellen, die sie erbt.

Beachten Sie, dass eine abstrakte Basisklasse mehr als eine Schnittstelle sein kann, da sie Datenelemente und Memberfunktionen enthalten kann, die nicht rein virtuell sind. Ein Äquivalent einer Schnittstelle wäre eine abstrakte Basisklasse ohne Daten mit rein virtuellen Funktionen.

Und wie Mark Ransom bemerkte, sollte eine abstrakte Basisklasse einen virtuellen Destruktor bereitstellen, genau wie jede Basisklasse.




In C ++ 11 können Sie die Vererbung ganz einfach vermeiden:

struct Interface {
  explicit Interface(SomeType& other)
  : foo([=](){ return other.my_foo(); }), 
    bar([=](){ return other.my_bar(); }), /*...*/ {}
  explicit Interface(SomeOtherType& other)
  : foo([=](){ return other.some_foo(); }), 
    bar([=](){ return other.some_bar(); }), /*...*/ {}
  // you can add more types here...

  // or use a generic constructor:
  template<class T>
  explicit Interface(T& other)
  : foo([=](){ return other.foo(); }), 
    bar([=](){ return other.bar(); }), /*...*/ {}

  const std::function<void(std::string)> foo;
  const std::function<void(std::string)> bar;
  // ...
};

In diesem Fall hat ein Interface Referenzsemantik, dh Sie müssen sicherstellen, dass das Objekt die Schnittstelle überdauert (es ist auch möglich, Schnittstellen mit Wertesemantik zu erstellen).

Diese Art von Schnittstellen hat ihre Vor- und Nachteile:

  • Sie benötigen mehr Speicher als vererbungsbasierter Polymorphismus.
  • Sie sind im Allgemeinen schneller als vererbungsbasierter Polymorphismus.
  • In den Fällen, in denen Sie den endgültigen Typ kennen, sind sie viel schneller! (Einige Compiler wie gcc und clang führen mehr Optimierungen in Typen durch, die keine Typen mit virtuellen Funktionen haben / erben).

Schließlich ist Vererbung die Wurzel allen Übels im komplexen Softwaredesign. In Sean Parents Wert Semantik und Konzepte-basierten Polymorphismus (sehr empfehlenswert, bessere Versionen dieser Technik werden dort erklärt) der folgende Fall wird untersucht:

Angenommen, ich habe eine Anwendung, in der ich meine Formen polymorph unter Verwendung der MyShape Oberfläche MyShape :

struct MyShape { virtual void my_draw() = 0; };
struct Circle : MyShape { void my_draw() { /* ... */ } };
// more shapes: e.g. triangle

In Ihrer Anwendung machen Sie das gleiche mit verschiedenen Formen, die die YourShape Schnittstelle verwenden:

struct YourShape { virtual void your_draw() = 0; };
struct Square : YourShape { void your_draw() { /* ... */ } };
/// some more shapes here...

Jetzt sagen Sie, dass Sie einige der Formen verwenden möchten, die ich in Ihrer Anwendung entwickelt habe. Konzeptionell haben unsere Shapes die gleiche Oberfläche, aber damit meine Shapes in Ihrer Anwendung funktionieren, müssten Sie meine Shapes wie folgt erweitern:

struct Circle : MyShape, YourShape { 
  void my_draw() { /*stays the same*/ };
  void your_draw() { my_draw(); }
};

Erstens ist das Ändern meiner Formen möglicherweise überhaupt nicht möglich. Darüber hinaus führt die Mehrfachvererbung zu Spaghetti-Code (stellen Sie sich vor, ein drittes Projekt kommt mit der TheirShape Schnittstelle ... was passiert, wenn sie auch ihre my_draw ?).

Update: Es gibt ein paar neue Referenzen über Nicht-Vererbungs-Polymorphie:




Meine Antwort ist im Grunde die gleiche wie die anderen, aber ich denke, es gibt zwei andere wichtige Dinge zu tun:

  1. Deklarieren Sie einen virtuellen Destruktor in Ihrer Schnittstelle oder erstellen Sie einen geschützten, nicht virtuellen, um undefiniertes Verhalten zu vermeiden, wenn jemand versucht, ein Objekt vom Typ IDemo zu löschen.

  2. Verwenden Sie die virtuelle Vererbung, um Probleme mit mehrfacher Vererbung zu vermeiden. (Es gibt häufiger Mehrfachvererbung, wenn wir Schnittstellen verwenden.)

Und wie andere Antworten:

  • Machen Sie eine Klasse mit rein virtuellen Methoden.
  • Verwenden Sie die Schnittstelle, indem Sie eine andere Klasse erstellen, die diese virtuellen Methoden überschreibt.

    class IDemo
    {
        public:
            virtual void OverrideMe() = 0;
            virtual ~IDemo() {}
    }
    

    Oder

    class IDemo
    {
        public:
            virtual void OverrideMe() = 0;
        protected:
            ~IDemo() {}
    }
    

    Und

    class Child : virtual public IDemo
    {
        public:
            virtual void OverrideMe()
            {
                //do stuff
            }
    }
    



Um die Antwort von bradtgmurray , möchten Sie vielleicht eine Ausnahme von der Liste der reinen virtuellen Methoden Ihrer Schnittstelle machen, indem Sie einen virtuellen Destruktor hinzufügen. Auf diese Weise können Sie die Zeigereigentümerschaft an eine andere Partei weitergeben, ohne die konkrete abgeleitete Klasse offenzulegen. Der Destruktor muss nichts tun, da die Schnittstelle keine konkreten Mitglieder hat. Es mag widersprüchlich erscheinen, eine Funktion sowohl als virtuell als auch als Inline zu definieren, aber vertraue mir - das ist es nicht.

class IDemo
{
    public:
        virtual ~IDemo() {}
        virtual void OverrideMe() = 0;
};

class Parent
{
    public:
        virtual ~Parent();
};

class Child : public Parent, public IDemo
{
    public:
        virtual void OverrideMe()
        {
            //do stuff
        }
};

Sie müssen keinen Body für den virtuellen Destruktor einfügen. Es stellt sich heraus, dass einige Compiler Probleme haben, einen leeren Destruktor zu optimieren, und Sie verwenden den Standard besser.




Hier ist die Definition der abstract class in C ++ Standard

n4687

13.4.2

Eine abstrakte Klasse ist eine Klasse, die nur als Basisklasse einer anderen Klasse verwendet werden kann. Objekte einer abstrakten Klasse können nur als Teilobjekte einer davon abgeleiteten Klasse erzeugt werden. Eine Klasse ist abstrakt, wenn sie mindestens eine reine virtuelle Funktion hat.




Soweit ich es testen konnte, ist es sehr wichtig, den virtuellen Destruktor hinzuzufügen. Ich verwende Objekte, die mit new und mit delete zerstört wurden.

Wenn Sie den virtuellen Destruktor nicht in der Schnittstelle hinzufügen, wird der Destruktor der geerbten Klasse nicht aufgerufen.

class IBase {
public:
    virtual ~IBase() {}; // destructor, use it to call destructor of the inherit classes
    virtual void Describe() = 0; // pure virtual method
};

class Tester : public IBase {
public:
    Tester(std::string name);
    virtual ~Tester();
    virtual void Describe();
private:
    std::string privatename;
};

Tester::Tester(std::string name) {
    std::cout << "Tester constructor" << std::endl;
    this->privatename = name;
}

Tester::~Tester() {
    std::cout << "Tester destructor" << std::endl;
}

void Tester::Describe() {
    std::cout << "I'm Tester [" << this->privatename << "]" << std::endl;
}


void descriptor(IBase * obj) {
    obj->Describe();
}

int main(int argc, char** argv) {

    std::cout << std::endl << "Tester Testing..." << std::endl;
    Tester * obj1 = new Tester("Declared with Tester");
    descriptor(obj1);
    delete obj1;

    std::cout << std::endl << "IBase Testing..." << std::endl;
    IBase * obj2 = new Tester("Declared with IBase");
    descriptor(obj2);
    delete obj2;

    // this is a bad usage of the object since it is created with "new" but there are no "delete"
    std::cout << std::endl << "Tester not defined..." << std::endl;
    descriptor(new Tester("Not defined"));


    return 0;
}

Wenn Sie den vorherigen Code ohne virtual ~IBase() {}; Sie werden sehen, dass der Destruktor Tester::~Tester() nie aufgerufen wird.




Wenn Sie den C ++ - Compiler von Microsoft verwenden, können Sie Folgendes tun:

struct __declspec(novtable) IFoo
{
    virtual void Bar() = 0;
};

class Child : public IFoo
{
public:
    virtual void Bar() override { /* Do Something */ }
}

Ich mag diesen Ansatz, weil er viel kleineren Interface-Code ergibt und die generierte Code-Größe deutlich kleiner sein kann. Die Verwendung von novtable entfernt alle Referenzen auf den vtable-Zeiger in dieser Klasse, sodass Sie sie niemals direkt instanziieren können. Siehe die Dokumentation hier - novtable .




Während es stimmt, dass virtual der De-facto-Standard ist, um eine Schnittstelle zu definieren, vergessen wir nicht das klassische C-ähnliche Muster, das mit einem Konstruktor in C ++ kommt:

struct IButton
{
    void (*click)(); // might be std::function(void()) if you prefer

    IButton( void (*click_)() )
    : click(click_)
    {
    }
};

// call as:
// (button.*click)();

Dies hat den Vorteil, dass Sie die Ereignislaufzeit erneut binden können, ohne Ihre Klasse neu konstruieren zu müssen (da C ++ keine Syntax zum Ändern von polymorphen Typen hat, ist dies eine Umgehung für Chamäleon-Klassen).

Tipps:

  • Sie können davon als eine Basisklasse erben (sowohl virtuelle als auch nicht-virtuelle sind erlaubt) und füllen click den Konstruktor Ihres Nachkommens.
  • Sie können den Funktionszeiger als ein protected Mitglied haben und eine public Referenz und / oder Getter haben.
  • Wie oben erwähnt, können Sie damit die Implementierung in Runtime wechseln. So ist es auch eine Möglichkeit, den Staat zu verwalten. Abhängig von der Anzahl der Änderungen von if s im Vergleich zum Status in Ihrem Code ist dies möglicherweise schneller als switch() es oder if s (der Turnaround wird bei 3-4 erwartet, aber immer zuerst messen.
  • Wenn Sie std::function<> über Funktionszeiger wählen, können Sie möglicherweise alle Ihre Objektdaten in IBase . Von diesem Punkt aus können Sie IBase für IBase (zB std::vector<IBase> wird funktionieren). Beachten Sie, dass dies je nach Compiler und STL-Code möglicherweise langsamer ist. Außerdem haben aktuelle Implementierungen von std::function<> tendenziell einen Overhead im Vergleich zu Funktionszeigern oder sogar virtuellen Funktionen (dies könnte sich in der Zukunft ändern).



Ein kleiner Zusatz zu dem, was dort oben steht:

Stellen Sie zunächst sicher, dass Ihr Destruktor auch rein virtuell ist

Zweitens möchten Sie möglicherweise virtuell (statt normalerweise) erben, wenn Sie das implementieren, nur für gute Maßnahmen.




Der Grund, warum Sie zusätzlich zu abstrakten Basisklassen in C # / Java eine spezielle Interface- Java ist, dass C # / Java keine Mehrfachvererbung unterstützt.

C ++ unterstützt mehrfache Vererbung und daher wird ein spezieller Typ nicht benötigt. Eine abstrakte Basisklasse ohne nicht abstrakte (rein virtuelle) Methoden entspricht funktional einer C # / Java-Schnittstelle.




Machen Sie eine Klasse mit rein virtuellen Methoden. Verwenden Sie die Schnittstelle, indem Sie eine andere Klasse erstellen, die diese virtuellen Methoden überschreibt.

Eine reine virtuelle Methode ist eine Klassenmethode, die als virtuell definiert und 0 zugewiesen ist.

class IDemo
{
    public:
        virtual ~IDemo() {}
        virtual void OverrideMe() = 0;
};

class Child : public IDemo
{
    public:
        virtual void OverrideMe()
        {
            //do stuff
        }
};



Anfänger

Einführungskurs, keine Programmiererfahrung

  • C ++ Primer * (Stanley Lippman, Josée Lajoie und Barbara E. Moo) ( aktualisiert für C ++ 11 ) Mit 1k Seiten ist dies eine sehr gründliche Einführung in C ++, die nahezu alles in der Sprache in einem zugänglichen Format abdeckt und sehr detailliert. Die fünfte Ausgabe (veröffentlicht am 16. August 2012) behandelt C ++ 11. [Review]

  • Programmierung: Grundlagen und Praxis mit C ++ (Bjarne Stroustrup, 2. Auflage - 25. Mai 2014) ( aktualisiert für C ++ 11 / C ++ 14 ) Eine Einführung in die Programmierung mit C ++ durch den Ersteller der Sprache. Eine gute Lektüre, die keine Programmiererfahrung voraussetzt, aber nicht nur für Anfänger geeignet ist.

* Nicht zu verwechseln mit C ++ Primer Plus (Stephen Prata), mit einer deutlich ungünstigeren review .

Einführungskurs mit vorheriger Programmiererfahrung

  • Eine Tour durch C ++ (Bjarne Stroustrup) ( 2. Auflage für C ++ 17 ) Die "Tour" ist eine kurze (ca. 180 Seiten und 14 Kapitel) Tutorial-Übersicht über alle Standard-C ++ - Funktionen (Sprache und Standardbibliothek sowie C ++) 11 ) auf einem mäßig hohen Niveau für Leute, die C ++ bereits kennen oder zumindest erfahrene Programmierer sind. Dieses Buch ist eine erweiterte Version des Materials, das die Kapitel 2-5 der C ++ - Programmiersprache, 4. Auflage, darstellt.

  • Accelerated C ++ (Andrew Koenig und Barbara Moo, 1. Auflage - 24. August 2000) Dies umfasst im Wesentlichen die gleichen Grundlagen wie die C ++ - Grundierung , jedoch nur ein Viertel ihres Platzes. Dies ist hauptsächlich darauf zurückzuführen, dass nicht versucht wird, eine Einführung in die Programmierung zu erhalten , sondern eine Einführung in C ++ für Personen, die zuvor in einer anderen Sprache programmiert haben. Die Lernkurve ist steiler, aber für diejenigen, die damit umgehen können, ist dies eine sehr kompakte Einführung in die Sprache. (In der Vergangenheit beschritt es Neuland, indem es das erste Anfängerbuch war, das einen modernen Ansatz zum Unterrichten der Sprache verwendete.) Trotzdem ist C ++, das es lehrt, rein C ++ 98. [Review]

Best Practices

  • Effective C ++ (Scott Meyers, 3. Auflage - 22. Mai 2005) Dies wurde mit dem Ziel verfasst, das beste zweite Buch zu sein, das C ++ - Programmierer lesen sollten, und es gelang ihm. Frühere Ausgaben waren für Programmierer gedacht, die aus C kommen, die dritte Auflage ändert dies und richtet sich an Programmierer, die aus Sprachen wie Java kommen. Es enthält ~ 50 leicht zu merkende Faustregeln und ihre Gründe in einem sehr zugänglichen (und angenehmen) Stil. Für C ++ 11 und C ++ 14 sind die Beispiele und einige Probleme veraltet, und Effective Modern C ++ sollte bevorzugt werden. [Review]

  • Effective Modern C ++ (Scott Meyers) Dies ist im Wesentlichen die neue Version von Effective C ++ , die sich an C ++ - Programmierer richtet, die den Übergang von C ++ 03 zu C ++ 11 und C ++ 14 vornehmen.

  • Effective STL (Scott Meyers) Damit soll der Teil der Standardbibliothek, der aus der STL stammt, dasselbe tun, was Effective C ++ mit der Sprache insgesamt getan hat: Es werden Faustregeln zusammen mit ihrer Begründung dargestellt. [Review]

Mittlere

  • Effektiveres C ++ (Scott Meyers) Noch mehr Faustregeln als effektives C ++ . Nicht so wichtig wie die im ersten Buch, aber trotzdem gut zu wissen.

  • Außergewöhnliches C ++ (Herb Sutter) Dieses Rätselpaket enthält eine der besten und gründlichsten Diskussionen über das ordnungsgemäße Ressourcenmanagement und die Ausnahmesicherheit in C ++ durch die Ressourcenerfassung (RAII) sowie die ausführliche Beschreibung einer Vielzahl Weitere Themen, darunter das Pimpl-Idiom, die Namenssuche, das Design guter Klassen und das C ++ - Speichermodell. [Review]

  • Mehr Außergewöhnliches C ++ (Herb Sutter) Umfasst zusätzliche Sicherheitsthemen für Ausnahmen, die nicht in Außergewöhnlichem C ++ behandelt werden , zusätzlich zur Diskussion der effektiven objektorientierten Programmierung in C ++ und der korrekten Verwendung der STL. [Review]

  • Außergewöhnlicher C ++ - Stil (Herb Sutter) Erläutert generische Programmierung, Optimierung und Ressourcenverwaltung. Dieses Buch bietet auch eine hervorragende Darstellung darüber, wie modularer Code in C ++ unter Verwendung von Nichtmitgliederfunktionen und des Prinzips der Einzelverantwortung geschrieben wird. [Review]

  • C ++ - Codierungsstandards (Herb Sutter und Andrei Alexandrescu) "Codierungsstandards" bedeutet hier nicht "wie viele Leerzeichen sollte ich meinen Code einrücken". Dieses Buch enthält 101 bewährte Vorgehensweisen, Idiome und häufige Fallstricke, die Ihnen beim Schreiben von Code helfen können. verständlicher und effizienter C ++ - Code. [Review]

  • C ++ - Vorlagen: Das vollständige Handbuch (David Vandevoorde und Nicolai M. Josuttis) Dies ist das Buch über Vorlagen, wie sie vor C ++ 11 existierten. Es deckt alles ab, von den Grundlagen bis hin zu den fortschrittlichsten Metaprogrammierungen für Schablonen, und erläutert jedes Detail (wie konzeptuell und wie sie implementiert werden) sowie viele häufige Fallstricke. Hat hervorragende Zusammenfassungen der One Definition Rule (ODR) und Überlastauflösung in den Anhängen. Eine zweite Ausgabe zu C ++ 11, C ++ 14 und C ++ 17 wurde bereits veröffentlicht. [Review]

Erweitert

  • Modernes C ++ - Design (Andrei Alexandrescu) Ein wegweisendes Buch über fortgeschrittene generische Programmiertechniken. Einführung in richtlinienbasiertes Design, Typenlisten und grundlegende generische Programmiersprachen. Anschließend wird erläutert, wie viele nützliche Entwurfsmuster (einschließlich kleiner Objektzuordnungen, Funktionen, Fabriken, Besucher und Multimethoden) effizient, modular und sauber unter Verwendung der generischen Programmierung implementiert werden können . [Review]

  • Metaprogrammierung von C ++ - Vorlagen (David Abrahams und Aleksey Gurtovoy)

  • C ++ Concurrency In Action (Anthony Williams) Ein Buch zur Unterstützung der C ++ 11-Parallelität, einschließlich der Thread-Bibliothek, der Atomics-Bibliothek, des C ++ - Speichermodells, Sperren und Mutexen sowie Fragen zum Entwerfen und Debuggen von Multithread-Anwendungen.

  • Fortgeschrittene C ++ - Metaprogrammierung (Davide Di Gennaro) Ein Handbuch zu TMP-Techniken vor C ++ 11, das sich mehr auf die Praxis als auf die Theorie konzentriert. Es gibt eine Unmenge von Ausschnitten in diesem Buch, von denen einige durch Typmerkmale überholt sind, aber die Techniken sind dennoch nützlich zu wissen. Wenn Sie die schrullige Formatierung / Bearbeitung in Kauf nehmen können, ist es einfacher zu lesen als Alexandrescu und lohnenswerter. Für erfahrene Entwickler besteht eine gute Chance, dass Sie etwas aus einer dunklen Ecke von C ++ (einer Eigenart) herausgreifen, die normalerweise nur durch umfangreiche Erfahrung entsteht.

Referenzstil - Alle Ebenen

  • Die C ++ - Programmiersprache (Bjarne Stroustrup) ( aktualisiert für C ++ 11 ) Die klassische Einführung in C ++ durch den Ersteller. Parallel zum klassischen K & R liest sich dies in der Tat sehr und umfasst alles von der Kernsprache über die Standardbibliothek, über Programmierparadigmen bis hin zur Philosophie der Sprache. [Review] Anmerkung: Alle Versionen des C ++ - Standards werden in dieser Frage nachverfolgt: Wo finde ich den aktuellen C ++ - Standard?

  • C ++ - Standardbibliothek - Tutorial und Referenz (Nicolai Josuttis) ( aktualisiert für C ++ 11 ) Die Einführung und Referenz für die C ++ - Standardbibliothek. Die zweite Ausgabe (veröffentlicht am 9. April 2012) umfasst C ++ 11. [Review]

  • Die C ++ IO-Streams und Locales (Angelika Langer und Klaus Kreft) Zu diesem Buch gibt es sehr wenig zu sagen, außer, wenn Sie etwas über Streams und Locales wissen möchten, dann ist dies der richtige Ort, um endgültige Antworten zu finden. [Review]

C ++ 11/14/17 /… Referenzen:

  • Der Standard C ++ 11/14/17 (INCITS / ISO / IEC 14882: 2011/2014/2017) Dies ist natürlich der letzte Schiedsrichter für alles, was C ++ ist oder nicht. Seien Sie sich jedoch bewusst, dass es nur als Referenz für erfahrene Benutzer gedacht ist, die viel Zeit und Mühe auf ihr Verständnis ausgeben möchten. Der C ++ 17-Standard wird in elektronischer Form für 198 Schweizer Franken veröffentlicht.

  • Der C ++ 17-Standard ist verfügbar, aber scheinbar nicht in einer kostengünstigen Form - 17 kostet er 198 Schweizer Franken (etwa 200 US-Dollar). Für die meisten Menschen ist der endgültige Entwurf vor der Standardisierung mehr als ausreichend (und kostenlos). Viele werden einen noch neueren Entwurf vorziehen und neue Funktionen dokumentieren, die wahrscheinlich in C ++ 20 enthalten sind.

  • Überblick über das neue C ++ (C ++ 11/14 ) (nur PDF) (Scott Meyers) ( aktualisiert für C ++ 1y / C ++ 14 ) Dies ist das Präsentationsmaterial (Folien und einige Vorlesungsunterlagen) eines Tagesschulungskurs angeboten von Scott Meyers, einem auf C ++ hoch angesehenen Autor. Obwohl die Liste der Artikel kurz ist, ist die Qualität hoch.

  • Die C ++ - Kernrichtlinien (C ++ 11/14/17 /…) (herausgegeben von Bjarne Stroustrup und Herb Sutter) sind ein sich entwickelndes Online-Dokument, das aus einer Reihe von Richtlinien für die Verwendung moderner C ++ - Quellen besteht. Die Richtlinien konzentrieren sich auf relativ übergeordnete Themen wie Schnittstellen, Ressourcenverwaltung, Speicherverwaltung und Parallelität, die sich auf die Anwendungsarchitektur und das Bibliotheksdesign auswirken. Das Projekt wurde auf der CppCon'15 von Bjarne Stroustrup und anderen angekündigt und begrüßt Beiträge der Community. Die meisten Richtlinien werden durch eine Begründung und Beispiele sowie Diskussionen über mögliche Werkzeugunterstützung ergänzt. Viele Regeln sind speziell dafür ausgelegt, von statischen Analysewerkzeugen automatisch überprüft zu werden.

  • Die C ++ Super-FAQ (Marshall Cline, Bjarne Stroustrup und andere) ist ein Bestreben der Standard C ++ Foundation, die zuvor von Marshall Cline und Bjarne Stroustrup individuell gepflegten C ++ - FAQs zu vereinheitlichen und neue Beiträge einzubeziehen. Die Artikel befassen sich meist mit Problemen auf mittlerer Ebene und werden oft mit einem humorvollen Ton geschrieben. Möglicherweise sind noch nicht alle Elemente mit der neuesten Ausgabe des C ++ - Standards vollständig auf dem neuesten Stand.

  • cppreference.com (C ++ 03/11/14/17 /…) (initiiert von Nate Kohl) ist ein Wiki, das die grundlegenden Kernsprachenmerkmale zusammenfasst und eine umfassende Dokumentation der C ++ - Standardbibliothek enthält. Die Dokumentation ist sehr präzise, ​​jedoch einfacher zu lesen als das offizielle Standarddokument und bietet aufgrund seines Wiki-Charakters eine bessere Navigation. Das Projekt dokumentiert alle Versionen des C ++ - Standards und die Site ermöglicht das Filtern der Anzeige nach einer bestimmten Version. Das Projekt wurde von Nate Kohl auf der CppCon'14 vorgestellt .

Klassiker / Älter

Hinweis: Einige in diesen Büchern enthaltene Informationen sind möglicherweise nicht auf dem neuesten Stand oder gelten nicht mehr als bewährte Methode.

  • Das Design und die Entwicklung von C ++ (Bjarne Stroustrup) Wenn Sie wissen wollen, warum die Sprache so ist, wie sie ist, dann finden Sie in diesem Buch Antworten. Dies umfasst alles vor der Standardisierung von C ++.

  • Überlegungen zu C ++ - (Andrew Koenig und Barbara Moo) [Review]

  • Fortgeschrittene C ++ - Programmierstile und -Idiome (James Coplien) Als Vorläufer der Musterbewegung werden viele C ++ - spezifische "Idiome" beschrieben. Es ist auf jeden Fall ein sehr gutes Buch und vielleicht noch eine Lektüre wert, wenn Sie sich die Zeit nehmen können, aber mit dem aktuellen C ++ recht alt und nicht auf dem neuesten Stand.

  • Großes C ++ - Softwaredesign (John Lakos) Lakos erläutert Techniken zur Verwaltung sehr großer C ++ - Softwareprojekte. Sicherlich eine gute Lektüre, wenn es nur aktuell wäre. Es wurde lange vor C ++ 98 geschrieben und lässt viele Features (z. B. Namensräume) vermissen, die für große Projekte wichtig sind. Wenn Sie in einem großen C ++ - Softwareprojekt arbeiten müssen, möchten Sie es vielleicht lesen, obwohl Sie mehr als ein Salz Salz mitnehmen müssen. Der erste Band einer Neuauflage wird 2018 erwartet .

  • Innerhalb des C ++ - Objektmodells (Stanley Lippman) Wenn Sie wissen möchten, wie virtuelle Elementfunktionen allgemein implementiert werden und wie Basisobjekte in einem Szenario mit mehreren Vererbungen allgemein im Speicher abgelegt werden und wie sich dies auf die Leistung auswirkt, sollten Sie dies tun gründliche Diskussionen über solche Themen finden.

  • Das kommentierte C ++ - Referenzhandbuch (Bjarne Stroustrup, Margaret A. Ellis) Dieses Buch ist ziemlich veraltet, da es die C ++ 2.0-Version von 1989 untersucht - Vorlagen, Ausnahmen, Namespaces und neue Besetzungen wurden noch nicht eingeführt. Das Buch durchläuft jedoch den gesamten C ++ - Standard der Zeit und erläutert die Gründe, die möglichen Implementierungen und Merkmale der Sprache. Dies ist kein Buch zum Erlernen von Programmierprinzipien und -mustern in C ++, sondern zum Verstehen aller Aspekte der C ++ - Sprache.

  • Denken in C ++ (Bruce Eckel, 2. Auflage, 2000). Zwei Bände; ist eine Reihe von Einführungsbüchern. Downloads: Band 1 , Band 2 . Leider sind sie durch eine Reihe trivialer Fehler beeinträchtigt (z. B. die Behauptung, dass temporäre const automatisch const ), ohne offizielle Errata-Liste. Eine teilweise Errata-Liste von Drittanbietern ist unter http://www.computersciencelab.com/Eckel.htm verfügbar, wird aber offenbar nicht gepflegt.

  • Wissenschaft und Technik C ++: Einführung in fortgeschrittene Techniken und Beispiele (John Barton und Lee Nackman) Es ist ein umfassendes und sehr detailliertes Buch, in dem versucht wurde, alle in C ++ verfügbaren Funktionen im Zusammenhang mit numerischen Methoden zu erklären und zu nutzen. Zu dieser Zeit wurden mehrere neue Techniken eingeführt, beispielsweise das Curiously Recurring Template Pattern (CRTP, auch Barton-Nackman-Trick genannt). Es war Pionier bei verschiedenen Techniken wie der Dimensionsanalyse und der automatischen Differenzierung. Das Programm enthielt viele kompilierbare und nützliche Codes, die vom Ausdrucks-Parser bis zum Lapack-Wrapper reichen. Der Code ist noch immer hier verfügbar: http://www.informit.com/store/scientific-and-engineering-c-plus-plus-an-introduction-9780201533934 . Leider sind die Bücher in Bezug auf Stil und C ++ - Funktionen etwas veraltet, jedoch war dies zu der Zeit (1994, vor dem STL) ein unglaublicher Kraftakt. Die Kapitel über die Vererbung von Dynamik sind etwas kompliziert zu verstehen und nicht sehr nützlich. Eine aktualisierte Version dieses klassischen Buches, die Bewegungssemantik und die aus der STL-Lektion gewonnenen Lektionen enthält, wäre sehr schön.





c++ inheritance interface abstract-class pure-virtual