= Operator spinnt?
-
Hallo allerseits

Ich habe eine variant-Klasse geschrieben, die ein beliebiges Objekt beinhalten kann. Ich kann allerdings u.a. das verhalten des = Operators nicht nachvollziehen. Wenn ich einem Variant-Objekt ein anderes Variant-Objekt zuweise, dann müsste doch das erste Objekt das ganze andere Objekt beinhalten und nicht nur dessen inhalt (in diesem Beispiel der String). Oder ist es ein Sonderfall weil es zwei Objekte vom selben Typ sind? Hat jemand eine Idee was da genau abgeht?
#ifndef VARIANT_H #define VARIANT_H #include <cstdlib> class variant { public: // constructor variant() { m_size = 0; m_data = NULL; } // initializer constructor template <typename T> variant(const T &obj) { store(&obj); } // copy constructor variant(const variant &v) { m_size = v.m_size; free(m_data); m_data = malloc(m_size); memcpy(m_data, v.m_data, m_size); } // destructor virtual ~variant() { free(m_data); } // = operator template <typename T> variant& operator = (const T &obj) { store(&obj); } // get object data template <typename T> T get() { return *((T*)m_data); } // get object size size_t size() { return m_size; } private: // store object in variant template<typename T> void store(const T *obj) { free(m_data); m_size = sizeof(T); m_data = malloc(m_size); memcpy(m_data, obj, m_size); } // object size size_t m_size; // object data void *m_data; }; #endifDas geht:
#include <cstdlib> #include <iostream> #include <string> #include "variant.h" using namespace std; int main(int argc, char *argv[]) { variant x = string("Hallo"); variant y; y = x; cout << y.get<string>() << endl; system("PAUSE"); return EXIT_SUCCESS; }Das geht nicht (crash), obwohl es meiner Meinung nach logischer wäre:
#include <cstdlib> #include <iostream> #include <string> #include "variant.h" using namespace std; int main(int argc, char *argv[]) { variant x = string("Hallo"); variant y; y = x; cout << (y.get<variant>()).get<string>() << endl; system("PAUSE"); return EXIT_SUCCESS; }
-
malloc -> nur PODs
hab gar nicht weitergelesen
-
Ein Templateoperator ist niemals ein Copyzuweisungsoperator und ein Templatekonstruktor niemals ein Copykonstruktor. Diese werden implizit durch den Compiler deklariert (da du es nicht tust) und dann entsprechend aufgerufen. Man könnte auch sagen, der erste Satz folgt aus dem Zweiten, aber oft lässt man den letzten Teil auch weg und dann sieht das plötzlich wie eine besondere Regel aus, obwohl es eigentlich keine ist.
-
Wenn ich die beiden folgenden methoden definiere:
template <typename T> variant& operator = (const T &obj)variant& operator = (const variant &v)Kann ich dann davon ausgehen, dass 1. immer dann verwendet wird, wenn 2. nicht geht?
-
Du solltest weiterhin die Selbstzuweisung mit:
if(this != &obj)ausschließen.
-
Eigentlich braucht er das nicht, sofern die Logik korrekt ist. Was allerdings nicht der Fall ist. Das würde ich eher ändern.
-
Zumindests beim Zuweisungsoperator fehlt ein "return *this;" ...
Daher kann die Zuweisung "y = x;" nur Müll ausgeben.(Falls das überhaupt so kompiliert!)
-
Langsam geht mir auf, dass meine Klasse ziemlicher Müll ist.

Ich kann ja mit sizeof gar nicht die korrekte Objektgrösse ermitteln. Ich müsste die Objekte jeweils mit new duplizieren. Da aber die daten in einem void-Pointer gespeichert werden, kann ich den Speicher nicht mit delete freigeben.
-
Deine Klasse funktioniert - zumindest solange du sie nur mit PODs füllst (POD=Plain Old Data - das sind vereinfacht ausgedrückt Datentypen, die auch in C vorkommen könnten). Wenn du mit vollwertigen C++ Klassen arbeiten willst, hast du schon ein Problem - du kannst mit deinem Ansatz nicht feststellen, welchen Datentyp du in deinem variant gespeichert hast, aber du brauchst diesen Typ, um deine Daten korrekt zu kopieren.