Templates (Sehen ,verstehen^^)
-
Wikinger75 schrieb:
das heißt es müsste dan so ausehen damit es mit der cpp funktioniert:
Es beherrscht (soviel ich weiß) nur der Comeau C++ Compiler eine Variante des export [Template in Header/Source verteilt, ohne cpp-inklude aus dem Header] (weder dein wxDev-C++ noch MSVC++ etc. können dies)
Templates schreibt man daher eigentlich immer komplett in den Header.
-
Was du machen kannst, ist folgendes:
// dat.hpp #ifndef DAT_HPP_ #define DAT_HPP_ template <class data> class DAT { private: data Var; public: data getData(); bool isEmpty(); void setData(data Wert); }; #inlcude "dat.impl"//Wichtige Stelle!! #endif// dat.impl using namespace std;//Verwende lieber std:: anstatt den Namespace komplett bekannt zu machen //----------> Getter! <----------// data DAT::getData() { return Var; } //----------> Prüfer! <----------// bool DAT::isEmpty() { if (Var == 0) {return true;} else {return false;} } //----------> Setter! <----------// void DAT::setData(data Wert) { Var = Wert; } //----------> TheEnd! <----------//
-
Firefighter schrieb:
Was du machen kannst, ist folgendes:
// dat.impl using namespace std;//Verwende lieber std:: anstatt den Namespace komplett bekannt zu machenNicht nur besser. using namespace gehört niemals in eine Datei die includiert wird (in der Regel Header, in diesem Fall aber auch die Implementierung).
-
asc schrieb:
Nicht nur besser. using namespace gehört niemals in eine Datei die includiert wird (in der Regel Header, in diesem Fall aber auch die Implementierung).
ist das ein dogma?
falls ja, widerspreche ich hiermit.
-
volkard schrieb:
asc schrieb:
Nicht nur besser. using namespace gehört niemals in eine Datei die includiert wird (in der Regel Header, in diesem Fall aber auch die Implementierung).
ist das ein dogma?
falls ja, widerspreche ich hiermit.Ganz ehrlich: Es gibt auch sinnvolle Regeln, und diese gehört dazu. Spätestens wenn man wegen einem unbedacht gesetzten using namespace Stundenlang in einem Projekt auf Fehlersuche ist, wird man dies merken.
Bessonders schön sind da noch die Komponenten vom C++ Builder: Wozu werden überhaupt Namensräume definiert, wenn diese am Ende des gleichen Headers mittels using namespace wieder global veröffentlicht werden?
-
asc schrieb:
Ganz ehrlich: Es gibt auch sinnvolle Regeln, und diese gehört dazu.
Auch für sinnvolle Regeln gibt es sinnvolle Ausnahmen.
Oder frei nach Simon2: Pauschalisierungen sind immer falsch!
asc schrieb:
Bessonders schön sind da noch die Komponenten vom C++ Builder: Wozu werden überhaupt Namensräume definiert, wenn diese am Ende des gleichen Headers mittels using namespace wieder global veröffentlicht werden?
Damit man im Kollisionsfalle den Namespace explizit angeben kann?
Zu den Gründen für das automatisch generierte "using namespace" hatte ich hier etwas geschrieben.
Wo ist der Nachteil in der Praxis?
-
audacia schrieb:
asc schrieb:
Ganz ehrlich: Es gibt auch sinnvolle Regeln, und diese gehört dazu.
Auch für sinnvolle Regeln gibt es sinnvolle Ausnahmen.
Oder frei nach Simon2: Pauschalisierungen sind immer falsch!
Gerade in einem Forum bei denen überwiegend Anfänger anfragen, finde ich sinnvolle Regeln besser. Das es immer Ausnahmen geben kann, mag sein. Ich gehe vom Regelfall der in 90% der Fälle sinnvoll ist aus (90:10 Regel).
audacia schrieb:
Zu den Gründen für das automatisch generierte "using namespace" hatte ich hier etwas geschrieben.
Wo ist der Nachteil in der Praxis?Der Nachteil ist: Ich habe zwei verschiedene Komponenten die, die gleichen Bezeichner verwenden. Nach dem hinzufügen der zweiten durfte ich erstmal den gesamten Code überarbeiten. Dann lieber kein using namespace, um nicht irgendwann erstmal nach den Fehlern suchen zu dürfen.
cu André
-
asc schrieb:
Der Nachteil ist: Ich habe zwei verschiedene Komponenten die, die gleichen Bezeichner verwenden.
Ob das using namespace nun im Header steht oder ob das der Autor der Komponente an den Anfang seiner .cpp-Datei setzt, ändert ja nun auch nichts

In der Tat wäre es aber ein reizvolles Refactoring, sämtliche Namen innerhalb einer Auswahl vollständig zu qualifizieren.
-
audacia schrieb:
In der Tat wäre es aber ein reizvolles Refactoring, sämtliche Namen innerhalb einer Auswahl vollständig zu qualifizieren.
Ich weiß, das gehört nicht zum Thread: Wann wird mein flehen nach mehr und vor allem auch funktionierenden Refactoringtools für den C++ Builder endlich erhört (Das eine das eh nicht funktioniert ist jedenfalls nicht ausreichend ;p).
-
Wenn alles gut läuft, in der kommenden Version, neben dem Class Explorer für C++.
-
#inlcude "dat.impl"//Wichtige Stelle!!muss die datei ".impl" heißen oder kann die auch anders heißen?
-
Wikinger75 schrieb:
#inlcude "dat.impl"//Wichtige Stelle!!muss die datei ".impl" heißen oder kann die auch anders heißen?
freier name.
aber bei .impl weiß sogar ich, was damit gemeint ist. die implementierung von templatefunktionen, gell?
-
gut danke leute^^
-
asc schrieb:
Ganz ehrlich: Es gibt auch sinnvolle Regeln, und diese gehört dazu.
sinnvoll? nein, nicht mit fettem "niemals" drin.
sobalds kein dogma mehr ist, geb ich dir recht.ich verwende entweder std oder vlib, aber ich will eigentlich nicht innerhalb eines projekts beide benutzen. da kann ich mir doch ein using namespace std oder using namespace vlib in den zentralen header knallen und dort umschalten.
-
ehm folegndes^^
habs jetzt so:
hpp// dat.hpp #ifndef DAT_HPP_ #define DAT_HPP_ template <class data> class DAT { private: data Var; public: data getData(); bool isEmpty(); void setData(data Wert); }; #include "dat.impl" #endifimpl
// dat.impl //----------> Getter! <----------// data DAT::getData() { return Var; } //----------> Prüfer! <----------// bool DAT::isEmpty() { if (Var == 0) {return true;} else {return false;} } //----------> Setter! <----------// void DAT::setData(data Wert) { Var = Wert; } //----------> TheEnd! <----------//Es gibt immer noch einen compiler fehler, auch wenn ich seh in h umbenene, naja werds wohl gleich in der hpp machen müssen^^
-
getData ist aber nicht in der klasse DAT, sondern in DAT<data>.
das ging glaub ich so:template <class data> data DAT<data>::getData() { return Var; }aber bis auf seltene ausnahmen würde ich mich damit nicht behängen und den code einfach in die klasse kloppen.
-
ich habs jetzt aber in eine header gemacht so wie ich es vorhin geschrieben habe und es ging ohne das <data>.
-
Wikinger75 schrieb:
muss die datei ".impl" heißen oder kann die auch anders heißen?
Kann auch anders heissen. Neben .hpp und .h sieht man oft auch .inl, .ipp oder .impl. Ich bevorzuge persönlich .inl (für Inline), da hat MSVC gerade einen eigenen Datentyp.
volkard schrieb:
aber bis auf seltene ausnahmen würde ich mich damit nicht behängen und den code einfach in die klasse kloppen.
Naja, ist auch ein wenig Geschmackssache. Ich mach oft eine Trennung, damit ich Schnittstelle und Implementierung sauber separiert habe. Auch wenn das manchmal auf komplizierte Funktionsdefinitionen herausläuft, gerade wenn noch ein
typedefdabei ist...
P.S. Getter sollte man
constmachen, da man nichts an der Klasse verändert und somit die Memberfunktion auch mit konstanten Instanzen aufrufen kann.
-
// DAT.hpp #ifndef DAT_HPP_ #define DAT_HPP_ template <class DATA> class DAT { private: DATA Var; public: DATA getData() const; bool isEmpty(); void setData(data Wert); }; //----------> Getter! <----------// DATA DAT<DATA>::getData() const { return Var; } //----------> Prüfer! <----------// bool DAT<DATA>::isEmpty() { if (Var == 0) {return true;} else {return false;} } //----------> Setter! <----------// void DAT<DATA>::setData(data Wert) { Var = Wert; } //----------> TheEnd! <----------// #endifEs ist in einer Datei und es funktioniert nicht.
-
Wikinger75 schrieb:
Es ist in einer Datei und es funktioniert nicht.
Das ist keine Fehlerbeschreibung!