Ist dies sinnvoll?
-
Hi,
ich habe eine frage zu folgender Klasse die ich eben im Netz gefunden habe:
template<typename T, unsigned int size> class basic_array { public: basic_array (void) : size_ (size), data_ (NULL) { if (size_ == 0) throw "Ungueltige Groesse"; data_ = new T [size_]; } ~basic_array (void) { if (data_ != NULL) { delete data_; data_ = NULL; } } T& operator[] (unsigned int id) { if (id > size_) throw "Zu hoher Zugriffswert!"; return (data_[id]); } private: T *data_; unsigned int size_; };
Ist sowas gut? ich mein 2 sicherheitsabfragen sind ja drin damit man keinen unzulässigen Speicherzugriff macht, aber lohnt sich das new und delete bzw. die ganze klasse?
Also ich empfand sie schon als praktisch aber was meint ihr?
-
Schmeiß den Code weg. Absoluter Unfug.
edit:Also ich empfand sie schon als praktisch aber was meint ihr?
Dann wäre entweder boost::array oder std::vector oder std::deque was für dich. (Wenn's wirklich nur um "praktische" Arrays geht.)
-
also ich weiß nicht, die klasse sollte besser so aussehen wegen speed:
template<typename T, unsigned int size> class basic_array { public: basic_array (void) : size_ (size), data_ (NULL) { if (size_ == 0) throw "Ungueltige Groesse"; } ~basic_array (void) { } T& operator[] (unsigned int id) { if (id > size_) throw "Zu hoher Zugriffswert!"; return (data_[id]); } private: T data_[size_]; unsigned int size_; };
dann könnte man die auch sehr gut fürs GameDev gebrauchen wie z.B. bei den VBOs von OpenGL oder den FVFs von Direct3D, die ja immer konstante Strukturen haben wollen. Klein, kurz und nicht zu überladen und kann das was sie soll für ein statisches Array.
Eigentlich ganz Praktisch.
-
alaa schrieb:
also ich weiß nicht, die klasse sollte besser so aussehen wegen speed:
Naja, immer noch nicht annähernd toll, oder?
Der Konstruktor ist recht amüsant. Die Redundanz ist auch nicht schlecht. Und und und...
Aber davon ab - kann fast soviel wie ein normales Array...
-
Ein sicheres, total in der funktionalität ausreichendes statisches array.
-
alaa schrieb:
Eigentlich ganz Praktisch.
Ja, fast so praktisch wie ein Copy & Paste von boost::array.
-
Habe mit boost noch nie gearbeitet, wenn ich bisher was brauchte hab ichs mir immer selber gecodet. vorallem wegen Lernfaktor und Lizenz sowie CopyRight
-
alaa schrieb:
Ein sicheres, total in der funktionalität ausreichendes statisches array.
codetechnisch totaler unfug!
1. punkt:
wozu eine variable size_ wenn size schon der template parameter ist.
2. punkt:
wieso eine exception werfen, wenn zur compilezeit schon klar ist, dass da was nicht stimmt.if (size_ == 0) throw "Ungueltige Groesse";
3. punkt
der springende punkt bei der klasse im anfangspost ist, dass das array aufm heap liegt, ist zwar langsamer, aber man belastet den stack nicht so stark, bei deiner version müsste man bei großen statischen arrays gleich das ganze objekt aufm heap packen, und genau sowas will man sich ja sparen. Vector kommt meiner meinung nach bei sowas auch nicht in frage, da er sich nicht exakt an die gewünschte größe anpassen lässt.
-
@otze:
also dann eher sowas:template<typename T, unsigned int size> class basic_array { public: basic_array (void) {} ~basic_array (void) {} inline T& operator[] (unsigned int id) { if (id > size) throw "Zu hoher Zugriffswert!"; return (data_[id]); } private: T data_[size]; };
Jedoch wie man einen Compilerfehler dabei ausgibt wenn size = 0 ist weiß ich nicht?
-
Durch Template-Spezialisierung z. B.. Ungefähr so:
template<bool> struct CompileTimeError; template<> struct CompileTimeError<true> { }; #define STATIC_CHECK(expr) (CompileTimeError<(expr) != 0>())
So kopiert aus "Modernes C++ Design" von Andrei Alexandrescu. Er führt das noch ein bisschen weiter, um die dabei generierte Fehlermeldung zu verbessern, aber das ist das Grundprinzip. Die Funktionsweise beruht darauf, dass CompileTimeError<false> nicht definiert ist. Und darüber wird sich dein Compiler dann beschweren.
Boost hat ein solches static assert übrigens auch schon dabeiWobei das in deinem Beispiel nicht notwendig ist, da ein Array mit einer Größe von 0 illegal ist und demzufolge sowieso einen Compiler-Fehler liefern würde