Template-variable initialisieren
-
Moin Leute!
Ich hab ein Problem mit meinem selbstgeschriebenen Template:
// Vektor auf vorgegebene Groesse setzen void SetSize(WORD iSize) { // vorgegebene Groesse > aktuelle Groesse if (iSize > std::vector<T>::size()) { T p; //Nullelemente einfuegen bis vorgegebene Groesse erreicht while (iSize > std::vector<T>::size()) { push_back (SetNullElement(p)); } } // vorgegebene Groesse <= aktuelle Groesse else { //Elemente loeschen bis vorgegebene Groesse erreicht while (iSize < std::vector<T>::size()) { pop_back(); } } }//Templatefunktionen zum Erzeugen von Nullelementen template<typename T> T SetNullElement(T) { T t; return t; } template<typename T> T* SetNullElement (T* p) { return NULL; }Beim Aufruf von SetNullElement mosert der Compiler rum, daß p nicht initialisiert ist. Eigentlich kein Problem, da durch die aufgerufene Funktion ja sichergestellt ist, das nichts mit der uninitialiserten Variable gemacht wird.
Beim Visual Studion poppt nun aber immer zur Laufzeit ein Fenster mit der Meldung "Run-Time Check Failure #3 - The variable 'p' is being used without being initialized." hoch. Da ich dieses Fenster reichlich nervig finde, würde ich das gerne abstellen. Aber wie muss ich denn die Variable initialisieren? Ich weiß ja erst zur Laufzeit, ob ein Objekt oder ein Pointer übergeben wird...
-
Das geht einfacher:
void MyClass:SetSize( unsigned int NewSize ) { MyVector.resize( NewSize ); }Fall 1: Der Vektor ist kleiner als die neue Größe:
std::vector wächst auf die neue Größe und initialisiert die neuen Elemente mit dem Default Konstruktor. Für Pointer Typen ist die Default Konstruktion eine Initialisierung mit 0.Fall 2: Der Vektor ist größer als die neue Größe:
std::vector zerstört am Ende seines Puffers so viele Elemente, wie die Differenz zwischen alter und neuer Größe beträgt. Für die zu zerstörenden Elemente wird der Destruktor aufgerufen.PS:
Templates werden IMMER zur Compile Time aufgelöst, du weißt also sicher, ob´s ein Zeiger ist oder nicht.
-
Abgesehen davon dass man das garantiert irgendwo abschalten kann: Dein Compiler hat recht. p wird uninitialisiert benutzt. Aber ich verstehe absolut nicht wofür. Was soll das p dort machen?
-
@DocShoe: Danke, irgendwie hab ich schon geahnt daß ich zu kompliziert denke und es eine triviale Lösung dafür gibt...
@SeppJ: Ich weiß das der Compiler recht hat. Es geht darum, ein "Nullobjekt" zu erzeugen (sprich entweder ein Nullpointer wenn das Template für Pointer verwendet wird oder ein Objekt was über den Standardkonstruktor erzeugt wird wenn das Template für Objekte verwendet wird). Somit ist es egal, ob die Variable initialisiert wird, da nicht auf sie zugegriffen wird.
-
Hellcat schrieb:
if (iSize > std::vector<T>::size())so ruft man keine nicht-statischen Elementfunktionen auf!
Hellcat schrieb:
push_back (SetNullElement(p));du darfst auch einfach push_back(T()); verwenden. Aber gleich myvector.resize(...); verwenden ist noch besser.
Dein SetNullElement gibt auch für eingebaute Typen wie int, double (u.s.w.) Müll zurück. Die haben keinen "Defaultkonstruktor".
Doof:T t; // uninitialisiert bei int, double, etc return t;Besser:
return T(); // liefert 0 bei int/double/...