Trennung von template-Klassen in Header- und Implementationsdatei



  • Hallo, bin erst neu hier im Forum, also möge man mich verschonen, falls der Post falsch gelandet ist.

    Nun zu meinem Problem: ich würde gerne eine Template-Klasse in Deklaration und Implementation trennen und habe dazu folgendes Format nutzen wollen: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file/495056#495056

    Als IDE nutze ich Visual Studio 2017. So, jetzt hat es in einem anderen Projekt (nur Test-Projekte, da ich C++ frisch lerne seit einigen Wochen) irgendwie durch Zufall funktioniert, dann hab ich ebenjene Dateien, die funktionieren, mal aus Spaß in zwei neue Dateien (.h und .cpp) kopiert, die Klassen umbenannt (der Logik nach zu urteilen, sollte es ja funktionieren) und siehe da: es geht nicht, auch in einem neuen leeren Test-Projekt geht es nicht!

    Um von dem ganzen theorielastigen Krempel wegzukommen, hier nun das neue leere Testprojekt ohne großartige Methoden und dazu noch die Fehlermeldungen:

    /* main.cpp */
    #include <iostream>
    #include "dynamic_array.h"
    
    int main(int argc, char* argv[]) {
        return 0;
    }
    
    /* dynamic_array.h */
    #pragma once
    
    template<typename T>
    class dynamic_array {
        private:
    
        public:
            explicit dynamic_array();
            ~dynamic_array();
    };
    
    #include "dynamic_array.cpp"
    
    /* dynamic_array.cpp */
    #include "dynamic_array.h"
    
    template<typename T>
    dynamic_array<T>::dynamic_array() {
    
    }
    
    template<typename T>
    dynamic_array<T>::~dynamic_array() {
    
    }
    

    Fehler 1:
    - Code: C2995
    - Beschreibung: "dynamic_array<T>::dynamic_array(void)": Funktionsvorlage wurde bereits definiert
    - Projekt: Project2
    - Datei: dynamic_array.cpp
    - Zeile: 6 (das ist die abschließende Klammer des implementierten Konstruktors)

    Fehler 2:
    - Code: C2995
    - Beschreibung: "dynamic_array<T>::~dynamic_array(void)": Funktionsvorlage wurde bereits definiert
    - Projekt: Project2
    - Datei: dynamic_array.cpp
    - Zeile: 11 (das ist die abschließende Klammer des implementierten Destruktors)

    Hoffe, die Informationen reichen erstmal aus und es ist irgendwie lösbar, das Problem.

    Gruß, ZondaKeN 👍



  • Dein Post ist nicht sehr übersichtlich, aber vermutlich ist das

    #include "dynamic_array.h"
    

    in dynamic_array.cpp das Problem.

    dynamic_array.cpp als Name ist nicht so geschickt. dynamic_array.impl würde keinen Compiler/IDE dazu verführen, die Datei zu übersetzen.



  • aber 1. würde ich dann keinerlei Syntax-Highlighting mehr bekommen und 2. schlägt er dann mit zig Fehlermeldungen um sich (https://pasteboard.co/Hf3z4pN.png)



  • Nenn die Dateien .inl oder .ipp
    Warum du Fehler bekommst weiss ich nicht.
    Wie wär's wenn du die 1:1 aus dem "Output" Fenster der IDE rauskopierst statt sie abzuschreiben? Also alles, inklusive Meldungen davor und danach - aus denen kann man dann nämlich meist entnehmen wo er meint dass das Ding davon schon definiert wurde.


  • Mod

    Bezüglich Syntaxhighlighting: Dann nenn sie .h und pack sie in irgendeinen Unterordner, zum Beispiel /impl/, von wo aus du sie dann im Header importierst. Das macht die Standardbibliothek vom GCC auch so.

    Bezüglich Fehlermeldungen:
    1. Die Dateien mit der Implementierung dürfen natürlich nicht selber den Header importieren, in dem sie selber importiert werden, denn das wäre schließlich zirkulär. In dem Header sollte logischerweise auch nichts drin stehen, was die Implementierung braucht, denn da stehen ja nur die Imports der Implementierung drin.
    2. Die Dateien mit der Implementierung dürfen auf keinen Fall dem Compiler zur direkten Übersetzung vorgelegt werden. Die werden ausschließlich indirekt über Header eingebunden.



  • ZondaKeN schrieb:

    2. schlägt er dann mit zig Fehlermeldungen um sich

    Nein, dann wird es problemlos übersetzt.



  • Warum tauchen dann ebenjene Fehlermeldungen auf (siehe Screenshot im pasteboard-Link)?



  • ZondaKeN schrieb:

    Warum tauchen dann ebenjene Fehlermeldungen auf (siehe Screenshot im pasteboard-Link)?

    Bin ich Hellseher?
    Du wirst da wohl etwas vermurkst haben.



  • manni66 schrieb:

    Bin ich Hellseher?
    Du wirst da wohl etwas vermurkst haben.

    Glaube schon, zumindest habe ich jetzt nicht gesehen, dass das Problem mit dem gegenseitigen include aus deinem ersten Post gefixt wurde.



  • SeppJ schrieb:

    1. Die Dateien mit der Implementierung dürfen natürlich nicht selber den Header importieren, in dem sie selber importiert werden, denn das wäre schließlich zirkulär. In dem Header sollte logischerweise auch nichts drin stehen, was die Implementierung braucht, denn da stehen ja nur die Imports der Implementierung drin.

    Doch, klar geht das, mach ich immer so.
    Das eine #include steht am Ende vom File das andere am Anfang, include Guards sind in beiden Files drinnen -> funktioniert, egal welches der beiden Files man inkludiert.
    Wenn man es weglässt, dann bekommt man je nach IDE nämlich wirklich Probleme mit dem Syntax-Highlighting -- weil der Parser dafür ohne die #includes halt nur Fehler sieht.

    SeppJ schrieb:

    2. Die Dateien mit der Implementierung dürfen auf keinen Fall dem Compiler zur direkten Übersetzung vorgelegt werden. Die werden ausschließlich indirekt über Header eingebunden.

    Müssen nicht bzw. macht keinen Sinn würde ich sagen. Aber so lange die nötigen #includes eben doch drin sind, geht es trotzdem.



  • NICE, perfekt! Danke, @hustbaer! Keine Ahnung, warum es mit #pragma once nicht geht, aber wofür kann man denn auch C, wenn es einem nicht aus der Patsche hilft, wenn C++ versagt... Danke!



  • NICE, danke! So geht es! Keine Ahnung, warum es mit #pragma once nicht geht, aber wofür kann man denn C, wenn es einem nicht aus der Patsche hilft, wenn C++ versagt... Danke! Kann man irgendwo den Beitrag als abgehakt eintragen oder 'ne beste Antwort vergeben? 😃



  • Sry für den Doublepost, wenn man das wo entfernen kann, möge man es mir zeigen...



  • pragma once ist im C++ Standard nicht definiert.



  • ZondaKeN schrieb:

    [...] wofür kann man denn auch C, wenn es einem nicht aus der Patsche hilft, wenn C++ versagt... Danke!

    Da bist Du selbst schuld:

    ZondaKeN schrieb:

    Als IDE nutze ich Visual Studio 2017.

    Zwischen C++ und VC++ besteht ein Unterschied: VC++ ist eingeschränkt. Ist für einfache Programme gedacht, da diese Sprache nicht so schnell abstürzt, wie C++, denn hier kann der Kompiler eibnige sachen korrigieren, was auch die Eingeschränktheit erklärt. Und ein Beweis dafür, dass VC++ kein Kompiler ist.



  • Swordfish schrieb:

    Zwischen C++ und VC++ besteht ein Unterschied: VC++ ist eingeschränkt. Ist für einfache Programme gedacht, da diese Sprache nicht so schnell abstürzt, wie C++, denn hier kann der Kompiler eibnige sachen korrigieren, was auch die Eingeschränktheit erklärt. Und ein Beweis dafür, dass VC++ kein Kompiler ist.

    Und welche IDE wäre deiner Meinung nach besser? Oder soll ich ganz von IDE weg und auf den GNU-Compiler setzen und in Notepad++ bearbeiten?



  • Swordfish schrieb:

    ZondaKeN schrieb:

    Als IDE nutze ich Visual Studio 2017.

    Zwischen C++ und VC++ besteht ein Unterschied: VC++ ist eingeschränkt. Ist für einfache Programme gedacht, da diese Sprache nicht so schnell abstürzt, wie C++, denn hier kann der Kompiler eibnige sachen korrigieren, was auch die Eingeschränktheit erklärt. Und ein Beweis dafür, dass VC++ kein Kompiler ist.

    Swordfish, bist du besoffen gewesen, als du das geschrieben hast?



  • ZondaKeN schrieb:

    NICE, danke! So geht es! Keine Ahnung, warum es mit #pragma once nicht geht, aber wofür kann man denn C, wenn es einem nicht aus der Patsche hilft, wenn C++ versagt... Danke!

    Hat bei mir auch immer mit #pragma once funktioniert 😕

    ZondaKeN schrieb:

    Kann man irgendwo den Beitrag als abgehakt eintragen oder 'ne beste Antwort vergeben? 😃

    Du kannst den ersten Beitrag in dem Thread editieren und dort sowas wie "[gelöst]" an den Titel anhängen.



  • Th69 schrieb:

    Swordfish schrieb:

    ZondaKeN schrieb:

    Als IDE nutze ich Visual Studio 2017.

    Zwischen C++ und VC++ besteht ein Unterschied: VC++ ist eingeschränkt. Ist für einfache Programme gedacht, da diese Sprache nicht so schnell abstürzt, wie C++, denn hier kann der Kompiler eibnige sachen korrigieren, was auch die Eingeschränktheit erklärt. Und ein Beweis dafür, dass VC++ kein Kompiler ist.

    Swordfish, bist du besoffen gewesen, als du das geschrieben hast?

    Nein, er zitiert hier nur einen sehr alten Beitrag von einem sehr speziellen Poster. Vielleicht gibts den ja noch irgendwo. Ich habe gerade keine Lust zum Suchen.



  • Braunstein schrieb:

    Nein, er zitiert hier nur einen sehr alten Beitrag von einem sehr speziellen Poster. Vielleicht gibts den ja noch irgendwo. Ich habe gerade keine Lust zum Suchen.

    Muss man aber auch erstmal wissen um das zu checken 🙂

    Ich vermute mal dashier wird das Original sein:
    https://www.c-plusplus.net/forum/p265352#265352


Anmelden zum Antworten