Kurz beurteilen!
-
Hilfe! Kann jemand kurz und schnell mal schauen, ob mein Code hier sauber ist? mein prof will heute noch wissen, ob ich template-programmierung verstanden habe!
danke!
-
Code vergessen... bin durch den wind
#include <iostream> #include <cstdlib> #include <string> #include <string> using namespace std; template <class T> class Allocator { public: Allocator() { } T* alloc() { return reinterpret_cast<T*>(malloc(sizeof(T))); } void destroy(T *obj) { obj->~T(); free(obj); } }; template <class T, class Alloc = Allocator<T> > class Test { private: T *val; Alloc *alloc; public: Test(T param) { alloc = new Alloc(); val = alloc->alloc(); *val = param; std::cout << *val << std::endl; } ~Test() { alloc->destroy(val); delete alloc; } }; int main() { Test<string> t("Ich mag Eis."); system("pause"); return 0; }
-
Hätteste statt 'kurz beurteilen' nicht irgendwas mit 'template' wählen können?
Da kann man so was leichter widerfinden, wenn man es suchen sollte
Zu deinem eigentlichen Anliegen kann ich nicht viel beitragen, außer warum
includierst du 'string' 2x ?
-
Was mich noch ein wenig verwirrt:
Zeile 6 oder Zeile 34 solltest du noch mal kritisch beurteilen!malloc/free und new/delete im selben Quelltext gibt es da keine andere Lösung?
-
template <class T, class Alloc = Allocator<T> > class Test { private: T *val; Alloc *alloc; public: Test(T param) { alloc = new Alloc(); val = alloc->alloc(); *val = param; std::cout << *val << std::endl; } ~Test() { alloc->destroy(val); delete alloc; } };würd ich so nicht machen...
template <class T, class Alloc = Allocator<T> > class Test { private: T *val; Alloc alloc; public: Test(T param) { val = alloc.alloc(); *val = param; //das hier ist so gar falsch... std::cout << *val << std::endl; } ~Test() { alloc.destroy(val); } };allocator sollte eine construct-function bereitstellen...
hab so was auch ma für die uni gemacht - so sieht mein allocator aus://includes wären #include <algorithm> //max #include <cstddef> //size_t / ptrdiff_t #include <new> //placement new //und namespace std_copyed kannst du mit std ersetzen, falls ihr die standard-lib verwenden dürft - wir durften es nicht und so musst ich selbst was schreiben ^^ //kann auch sein, dass manchmal kein namespace mit davor steht, weil der allocator auch im namespace std_copyed steht^^ #ifdef COMPILER_MSVC # pragma warning(push, 3) //http://msdn.microsoft.com/en-us/library/26kb9fy0.aspx # pragma warning(disable: 4100) //C4100 can also be issued when code calls a destructor on a otherwise unreferenced parameter of primitive type. This is a limitation of the Visual C++ compiler. #endif template <typename T> class allocator { public: typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef std_copyed::ptrdiff_t difference_type; typedef std_copyed::size_t size_type; template<class T_> struct rebind { typedef typename allocator<T_> other; }; public: allocator() {} template<typename T_> allocator(const allocator<T_> &) {} pointer address(reference r) const { return &r; } const_pointer address(const_reference r) const { return &r; } pointer allocate(size_type count, allocator<void>::const_pointer = nullptr) { size_type object_size = sizeof(T); size_type byte_count = object_size * count; void* address = ::operator new(byte_count); return reinterpret_cast<pointer> (address); } void deallocate(pointer p, size_type /*count*/) { return ::operator delete(p); } void construct(pointer p, const_reference value) { ::new(p) T(value); } void destroy(pointer p) { p->~value_type(); } size_type max_size() const { size_type addresses = size_type(~0); size_type object_size = sizeof(T); return max(addresses/object_size, 1); //allocate(max_size()) shall gave us a well defined behavior - and allocate(0) is undefined } }; template < > struct allocator <void> { typedef const void* const_pointer; typedef void* pointer; }; template<typename T> void swap(typename allocator<T> &lhs, typename allocator<T> &rhs) { /*do nothing*/ } #ifdef COMPILER_MSVC # pragma warning(pop) #endifbenutzung wäre so in etwa:
template< typename T, typename TAlloc = allocator<T> > struct x { private: TAlloc alloc; T* a; public: x() //: alloc() --- wird implizit aufgerufen, würd ich also weglassen ^^ { a = alloc.allocate(1); try { alloc.construct(a, T()); } catch(...) { alloc.deallocate(a, 1); throw; } } ~x() { alloc.deallocate(a, 1); } } int main() { x a; x b; }bb
ich hoffe, es hilft dir ein wenig - falls nicht, dann frag einfach ^^
edit: hatte noch was vergessen ^^
-
> *val = param; //das hier ist so gar falsch...
Wieso?

Dein Allokator ist ja im STL-Stil! Ich wollte das nicht soo komplex machen.
-
ok - dann machst du es eben anders ^^
auf jeden fall passiert beim assignment operator ja im prinzip (in der praxis sieht die reihenfolge anders aus, aber das soll hier nicht stören):- lösche lhs
- kopiere rhs nach lhsso bald T also ein typ ist, der einen destruktor besitzt, wird der aufgerufen - leider befindet sich da aber nicht wirklich ein objekt - es wurde bisher nur speicher angefordert und an der stelle steht irgendetwas...
dafür gibt es das placement new - was hier durch construct gekapselt wird..dem zu folge brauchst du mindestens das hier:
template <typename T> struct allocator { typedef std::size_t size_type; pointer allocate(size_type count = size_type(1)) { size_type object_size = sizeof(T); size_type byte_count = object_size * count; void* address = ::operator new(byte_count); return reinterpret_cast<pointer> (address); } void deallocate(pointer p) { return ::operator delete(p); } void construct(pointer p, const_reference value) { ::new(p) T(value); //erstelle an position p das objekt T mit dem wert value } void destroy(pointer p) { p->~value_type(); } };dabei fällt mir gerade auf, dass ich vergessen hatte, destroy in dem bsp aufzurufen...
bb