klasse nicht geklariert, obwohl sie es sein müsste?!



  • Ah, haha, sehr gut. Hast vollkommen Recht. Das wars. Ich hab die mat.cpp direkt kompiliert, was dann natürlich ging. 🙄



  • Dobi schrieb:

    Allerdings hat es sich (schon allein der Übersichtlichkeit halber) durchgesetzt, dass man die Definitionen einfach mit in die .h schreibt, die cpp nicht includiert und da nur den Kram drin hat, der nicht sichtbar sein muss. Dann passt es auch wieder zum normalen .h-.cpp-Konzept. Das würde ich auch empfehlen.

    Was daran übersichtlich sein soll, kann ich jetzt überhaupt nicht nachvollziehen. In ein headerfile sollen die Definitionen und nichts anderes.
    Alle eigentlichen Codes ins cpp. Wenn da was keine Templates drin hat, hat man schnell zwei defines angebracht, so dass sich das cpp auch trotz des mit enthaltenen template codes problemlos kompilieren lässt.
    So ist dann aber alles schön so zusammen wie es auch bei allen nicht-Template-Klassen ist.



  • ccpete schrieb:

    Was daran übersichtlich sein soll, kann ich jetzt überhaupt nicht nachvollziehen. In ein headerfile sollen die Definitionen und nichts anderes.

    Ein Template funktioniert aber nicht nach den "üblichen" Maßstäben, und es ist mit Sicherheit ungewöhnlicher ein include auf eine cpp zu machen, als eine Definition in die Header zu schreiben (und wenn schon, mit einer Endung die auf den Sonderfall hinweist. z.B. tmpl statt cpp).



  • asc schrieb:

    Ein Template funktioniert aber nicht nach den "üblichen" Maßstäben,

    Wohl war, aber es lässt sich so umsetzen, dass es genauso mit einbezogen werden kann wie eine ganz normale Klasse - Und dies macht in meinen Augen mehr Sinn, als etwas wie

    asc schrieb:

    (...mit einer Endung die auf den Sonderfall hinweist. z.B. tmpl statt cpp).

    Denn ich sehe hier keinen Mehrnutzen. Oder was nützt es mir, wenn ich die Endung sehe und dann nachschauen muss: "scheisse, was ist denn das für n'ding?".
    Und wenn ich dann noch Teile separat kompilieren muss, zB wegen einer Spezialisierung, dann soll das nochmals in ein separates File usw usw? Ne Danke, da ist doch der gute alte Aufbau einmal .hpp und einmal .cpp viel angenehmer.



  • ccpete schrieb:

    ...da ist doch der gute alte Aufbau einmal .hpp und einmal .cpp viel angenehmer.

    Ich hoffe das niemand mit deinen Projekten arbeiten muss, und sich erstmal wundert, warum eine cpp inkludiert wird.

    Zumal man dann noch in eine ganz andere Falle laufen kann: Die meisten Entwickler erwarten, das ein Include, das in einer cpp gemacht wird, oder ein using namespace, nur in diesem verwendet wird. In diesem Fall gilt dies aber alles nicht. Wehe dem der das nicht beachtet...



  • asc schrieb:

    Ich hoffe das niemand mit deinen Projekten arbeiten muss, und sich erstmal wundert, warum eine cpp inkludiert wird.

    Wenn er das tut, hat er das gleiche Problem wie mit nem *.tmp^^
    Aber für den Gebrauch ists viel intuitiver.

    asc schrieb:

    Zumal man dann noch in eine ganz andere Falle laufen kann: Die meisten Entwickler erwarten, das ein Include, das in einer cpp gemacht wird, oder ein using namespace, nur in diesem verwendet wird. In diesem Fall gilt dies aber alles nicht. Wehe dem der das nicht beachtet...

    Das soll ne Falle sein?!

    Wie gesagt: Man kann (ohne viel Aufwand) den Code so schreiben, dass sich alles so verwenden lässt als wärs ne ganz normale Klasse. Dass man dann kein using namespace oben hin setzt, versteht sich wohl... 🙄



  • ccpete schrieb:

    asc schrieb:

    Ich hoffe das niemand mit deinen Projekten arbeiten muss, und sich erstmal wundert, warum eine cpp inkludiert wird.

    Wenn er das tut, hat er das gleiche Problem wie mit nem *.tmp^^
    Aber für den Gebrauch ists viel intuitiver.

    Naja, wenn die Dateien immer .tempalte oder sonstwas heißen, muss man sich das nur einmal merken und weiß dann Bescheid.
    Wenn man das nicht tut, muss man bei jeder cpp erneut gucken, ob es sich um eine eigene Übersetzungseinheit handelt oder das Ding sichtbar ist (schon allein für die von dir erwähnte namespace-Frage). Für meinen Geschmack ist das eher ne Frickellösung, weil kein Compiler "export" hinbekommen hat.
    Natürlich ist es Geschmackssache, aber warum man unbedingt an "Keine Definitionen in Hs" festhalten sollte, verstehe ich nicht. Für mich, wie für viele andere auch, ist das andere halt intuitiver.
    Eigentlich sind es ja eh auch gar keine Definitionen, sondern Definitionstemplates. 😉
    Anstelle von "Hs für Deklarationen, cpps für Definitionen" kann mans auch als "Hs für sichtbares, cpp für rangelinktes" beschreiben.
    Dann hat man Templates und Inlines schon drin.
    Apropos: Nach deinem Konzept dürfte man gar keine Inlinememberfunktionen haben, oder? :p



  • Dobi schrieb:

    Naja, wenn die Dateien immer .tempalte oder sonstwas heißen, muss man sich das nur einmal merken und weiß dann Bescheid.

    Wenn man das nicht tut, muss man bei jeder cpp erneut gucken, ob es sich um eine eigene Übersetzungseinheit handelt oder das Ding sichtbar ist (schon allein für die von dir erwähnte namespace-Frage).

    Naja, das ist doch gar nicht nötig. Du kannst mit define guards in der .cpp die Templatefunktionen sauber von "normalen" Funktionsdefinitionen trennen, dafür brauchst du nur ein einziges define. Der Teil mit den Templatefunktionen sieht dann ganz so aus, wie er das in der .hpp auch würde, und der andere sieht aus wie n'ganz normales .cpp File. Um using und andere Dinge musst du dich da nicht mehr kümmern. Dann kannst du wie mit anderen Klassen dein Templateheaderfile includen (das selber dann nur den template Teil der .cpp included) und ausserdem für den anderen Teil einfach die .cpp kompilieren ohne dass sich da was beisst

    Dobi schrieb:

    Für meinen Geschmack ist das eher ne Frickellösung

    Stimmt in dem Sinne, dass es natürlich etwas aufwändiger ist, als alles in den header reinzuschreiben.

    Dobi schrieb:

    Natürlich ist es Geschmackssache, aber warum man unbedingt an "Keine Definitionen in Hs" festhalten sollte, verstehe ich nicht.

    Um dies gehts mir ja gar nicht grundsätzlich. Wie gesagt Geschmackssache, aber ich persönlich finde es angenehm, dass ich, wenn ich die Definition einer Funktion suche, ins .cpp-File schauen kann und wenn ich nur die Deklaration benötige, diese im .hpp-File finde. Und da muss ich mich dann eben nich drum kümmern, ob die Klasse da jetzt n'Template war oder nicht...

    Und dasselbe auch für die Benützung, Template oder nicht, Spezialisierungen oder nicht, ich kann immer die gleiche Regel anwenden (Stichwort:makefile): Den header includen, das .cpp kompilieren und linken.

    Mag sein, dass das nicht üblich ist, aber praktikabler finde ich dies jetzt durchaus.



  • Ok. Jetzt interessiert mich noch, wie du das mit den Inlinememberfunktionen in normalen Klassen machst. 🙂



  • Dobi schrieb:

    ...Für meinen Geschmack ist das eher ne Frickellösung, weil kein Compiler "export" hinbekommen hat...

    Diese Aussage stimmt nicht ganz, mindestens der Comeau Compiler hat dies tatsächlich (mit sehr langer Entwicklungszeit) hinbekommen, nun fällt das mit dem neuen Standard aber eh wieder weg (Dürfte für den Comeau-Entwickler recht ärgerlich sein, anderseits ärgere ich mich wiederum über die extrem langen Zyklen beim Comeau...).



  • Dobi schrieb:

    Ok. Jetzt interessiert mich noch, wie du das mit den Inlinememberfunktionen in normalen Klassen machst. 🙂

    Was soll damit sein?



  • Ok, wenn du bei nichttemplatigen Klassen auch Foo.h, Foo_sichtbare_Definitionen.cpp und Foo_unsichtbare_Definitionen.cpp benutzt, erübrigt sich die Frage natürlich. 😉



  • also ich mach das immer folgendermaßen mit klassen die sowohl template-funktionen als auch nicht template funktionen hat:
    header foo.h

    #ifndef __foo_h__
    #define __foo_h__
    
    class foo
    {
      //normale- und template-funktion deklarationen
    };
    
    #ifndef __foo_template__
    #define __foo_template__
    
    #include "foo.cpp"
    
    #undef __foo_template__
    #endif
    
    #endif
    

    definition foo.cpp

    #ifndef __foo_cpp__
    #define __foo_cpp__
    
    #include "foo.h"
    
    #ifndef __foo_template__
    //nicht-template-funktion definitionen
    #endif
    
    //template-funktion definitionen
    
    #endif
    

    das funktioniert bis jetzt immer sehr gut. wenn es allerdings ein problem damit gibt, wäre ich natürlich interessiert es zu erfahren.



  • FreakyBKA schrieb:

    das funktioniert bis jetzt immer sehr gut. wenn es allerdings ein problem damit gibt, wäre ich natürlich interessiert es zu erfahren.

    Das funktioniert solange gut, bis du mit jemand anderem zusammenarbeitest. Der wird dich nämlich wegen der Spaghetti-includes in der Kaffeetasse ertränken...
    Wer soll sowas denn nachvollziehen?

    Und das alles nur, damit die Definitionen der Template-Funktionen nicht im Header stehn müssen?



  • also ich für meinen geschmack finde es gut wenn deklarationen und definitionen getrennt sind. wenn dann soll er mich bitte im tee ertränken, ich trink nämlich keinen kaffee 😉
    gibts irgendwelche anderweitigen probleme mit dieser umsetzung, die nichts mit dem geschmack bzgl. des programmierstils zu tun haben :p



  • FreakyBKA schrieb:

    also ich für meinen geschmack finde es gut wenn deklarationen und definitionen getrennt sind.

    Finde ich auch gut, aber trotzdem komme ich ohne das Gefrickel klar. Warum lagerst du die Funktionstemplate-Definitionen nicht in eine separate .inl-Datei aus, die du am Ende des Headers inkludierst?



  • Ja, gibt es 😉
    Sobald du nämlich eine Library entwickelst und nur die Header weitergeben willst...



  • also mit library-entwicklung hab ich mich noch nicht auseinandergesetzt, weiß auch nicht wie das geht, gibts dafür literatur oder gute online-quellen?
    dabei stell ich mir auch grad die frage warum man nur die header reinpacken sollte, müssen die definitionen nicht auch irgendwie mit rein?



  • Dobi schrieb:

    Ok, wenn du bei nichttemplatigen Klassen auch Foo.h, Foo_sichtbare_Definitionen.cpp und Foo_unsichtbare_Definitionen.cpp benutzt, erübrigt sich die Frage natürlich. 😉

    Och, jetzt komm aber, ist das dein Ernst? 🙂
    Wer so engstirnig ist, dem ist nicht mehr zu helfen. Einen primitiven Konstruktor schreib ich zB natürlich auch gleich anstatt einer Deklaration fertig hin.
    Du würdest also, wenn dadurch keine Redundanzen mit doppeltem Code entstehen würden, einfach alles in ein File reinschreiben? 😉

    Im Endeffekt ist das doch ganz einfach ein doch noch recht simpler(!) Versuch, separation zumindest "filetechnisch" auch ohne export hinzukriegen. Und separation ist doch immer noch eines der Grundprinzipien von C++ und zumindest meiner Meinung nach der Übersicht recht dienlich.

    pumuckl schrieb:

    Wer soll sowas denn nachvollziehen?

    Ja wirklich seehr anspruchsvoll 😉 Da programmiert man die kompliziertesten Konstrukte, wo x Funktionen und Objekte miteinander zusammenspielen müssen, aber sowas ist dann zuviel..?

    @FreakyBKA: Das läuft perfekt, solange du weisst, was du tust 🤡



  • ccpete schrieb:

    pumuckl schrieb:

    Wer soll sowas denn nachvollziehen?

    Ja wirklich seehr anspruchsvoll 😉 Da programmiert man die kompliziertesten Konstrukte, wo x Funktionen und Objekte miteinander zusammenspielen müssen, aber sowas ist dann zuviel..?

    Unnötige Komplexität ist zuviel, ja. Klar kann man sowas machen, und wenn der Kollege, der den Kram am Ende warten muss, genug Zeit rein steckt, wird er es sicher auch nachvollziehen können. Trotzdem gilt, dass Klarheit und Einfachheit gewinnt. Das gilt auch für die komplizierten Konstrukte mit den x Funktionen und Objekten. Die kann man meistens so entheddern (durch Indirektion und Kapselung), dass x relativ klein (einstellig) wird.


Anmelden zum Antworten