C++ Klassen aufteilen



  • Karldin schrieb:

    Ist es eigentlich nötig oder eine Stilfrage, eine C++ Klasse in Header / Implementierungsdatei aufzuspalten?

    Bei großen Projekten ist es notwendig, so viel wie möglich zu verbergen, sonst dauert das Kompilieren Jahre.



  • Ne Headerdatei ist eigentlich nur eine Schnittstellenbeschreibung. Schnittstelle ist dabei im weitestens Sinne zu verstehen. Normalerweise interessiert es einen Klassen-Benutzer nicht, wie die Implementierung aussieht. Deshalb lagert man die Impl. in die cpp aus.

    Ein zweiter Punkt ist natürlich, wie lolz bereits sagt, die Compile-Zeit. Wenn du inkludierst, und das vielleicht 100x in deinem Projekt hast, und du nur ein Zeichen in der Header-Implementierung änderst, muß auch 100x neu kompiliert werden. Wenn du das eine Zeichen aber nur in der cpp-Datei änderst, wird diese nur einmal kompiliert. Und die anderen 100 Inkludierungen werden davon nicht betroffen sein. Weil die Schnittstelle sich nicht geändert hat ➡ weil die Implementierung nicht interessiert.

    Klar, wenn du die Schnittstelle änderst, ist der Compile-Zeit-Vorteil für den einen Moment über den Haufen. Aber immer noch besser, als wenn man bei jeder Implementierungsänderung alles kompilieren muß.



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum Rund um die Programmierung in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • #ifndef FOO_H__INCLUDED
    #define FOO_H__INCLUDED
    
    #if (_MSC_VER > 1000)
        #pragma once
    #endif // (_MSC_VER > 1000)
    
    class Foo 
    {
    public:
        Foo();
        Foo(const unsigned int&);
    
    public:
        void set_bar(const unsigned int& value) { m_bar= value; }
        unsigned int get_bar() const { return m_bar; }
    
    private:
        unsigned int m_bar;
    };
    
    #endif // FOO_H__INCLUDED
    
    #include "Foo.h"
    
    Foo::Foo() : m_bar(0)
    {
    }
    
    Foo::Foo(const unsigned int& value) : m_bar(value)
    {
    }
    

    🙂 so würde ich es machen ^^



  • Einen wichtigen Punkt haben wir (alle) vergessen:

    Die Implementierung würde in jede Übersetzungseinheit geschrieben werden, das kann zu bösen Seiteneffekten führen, wenn du Funktionen mit statischen Variablen hast.



  • lolz schrieb:

    Die Implementierung würde in jede Übersetzungseinheit geschrieben werden, das kann zu bösen Seiteneffekten führen, wenn du Funktionen mit statischen Variablen hast.

    Es würde zunächst mal Linkerfehler wegen mehrfacher Definitionen hageln. Aber wir benutzen ja inline, wenn wir Funktionen in Headerdateien stehen lassen, und dann fällt auch das static-Problem weg.



  • Hallo,

    an dieser Stelle finde ich es auch hilfreich das Problem der gegenseitigen Einbindung zweier Headerdateien zu erwähnen.

    Es gibt zwei Klassen, A und B. Klasse A wird in der Headerdatei a.h deklariert und implementiert. Klasse B wird in der Headerdatei b.h deklariert und implementiert. Nun benötigt Klasse A für die Implementierung Klasse B - muss also b.h inkludieren. Genauso benötigt Klasse B für die Implementierung Klasse A und bindet somit a.h ein.

    Nun entsteht ein Problem: Die Headerdateien binden sich nun rekursiv in einer Endlosschleife ein, bis der Compiler abbricht.

    Lösung: Wir trennen Deklaration und Implementierung. Klasse A wird in a.h deklariert und in a.cpp implementiert (genauso wird mit Klasse B verfahren). Nun wird in den Headerdateien mit Zeigern gearbeitet und die jeweils notwendige Klasse per Vorwärtsdeklaration (class A;) bekanntgegeben. Ferner ist es notwendig in der Implementierungsdatei die notwendige Klassendeklaration bekanntzugeben/einzubinden (eine Vorwärtsdeklaration reicht meist nicht aus).

    Grüße Martin



  • der :: operator ist eine der dümmsten "features" überhaupt. zum glück gibt es den in weniger verpfuschten programmiersprachen nicht.



  • Danke für eure Antworten. Na dann teilt man wohl besser auf.



  • feststellung schrieb:

    der :: operator ist eine der dümmsten "features" überhaupt. zum glück gibt es den in weniger verpfuschten programmiersprachen nicht.

    Wieso das?

    @Bashar: Ja, inline ist recht nützlich, aber man kann leider nicht alles inline lösen 😉


Anmelden zum Antworten