Dynamisches Referenzen-Array
-
Hi,
ich habe bisher in C/C++ immer mit Pointern gearbeitet.
Nun wollte ich der Vorteile von Referenzen wegen (und auch wegen der Herausforderung des Unbekannten bzw. weniger Bekannten
) in meinem aktuellen Projekt soweit es geht auf Pointer verzichten und ausschliesslich Referenzen arbeiten.Dies wollte ich auch gleich mit der ersten Klasse, der Template-Klasse "DynamicArray" (ich arbeite ausserdem auch das erste mal mit Templates), welche wie der Name schon sagt als eine Klasse zur Verwaltung eines dynamischen Arrays beliebigen Inhalts (vorwiegend von der Klasse string => DynamicStringArray) gedacht ist.
Intern soll optimalerweise ein dynamischen Array aus Referenzen verwaltet werden (derzeit ists allerdings ein Pointer-Array, siehe unten).//C++ Klasse DynamicArray #pragma once template <class T> class DynamicArray { private: T** data; int count; int capacity; //template <class T> void move(int from,int pos) { // } public: //template <class T> DynamicArray(void) { data = NULL; count = 0; capacity = 0; } //template <class T> void setCapacity(int cap) { cap=count; data = (T**)realloc(data,sizeof(T)*cap); } //template <class T> int add(T const& _data) { count++; setCapacity(count); data[count-1]=_data; } //template <class T> int remove(int index) { // } //template <class T> void insert(int index,T const& _data) { // } //template <class T> int getCount() { return count; } //template <class T> T& operator[](int index) { return data[index]; } //template <class T> ~DynamicArray(void) { } };//Aufruf z.b. mit string/Cstring DynamicArray<string> arr; string a; arr.add(a);Leider erhalte ich folgende Fehlermeldung und kann zwar das Problem erkennen, finde aber leider keine Lösung (weder bei Google noch hier):
1>d:\dev\weirdhospital_neu_ogre\app\weirdhospital2\weirdhospital\dynamicarray.h(50) : error C2440: '=' : cannot convert from 'const std::string' to 'std::string *'Wenn ich nun von der Fehlermeldung ausgehe liegt das Problem darin das ich beim hinzufügen von Elementen eine Referenz in ein dynamisches Pointer-Array speichere was logischerweise auch nicht gehen dürfte.
Wie stelle ich also nun an das ich entweder aus einer Referenz einen vollwertigen Pointer (inkl. in umgekehrte Richtung d.h. Pointer in Referenz für Rückgabe) mache oder aus dem Pointer-Array in der Klasse ein Refenzen-Array mache ?
Für eure Hilfe wäre ich euch sehr dankbar, da ich bei den Referenzen + Co. noch nicht so geübt bin und da darüber leider nicht so viel zu finden ist wie über Pointer !
Vielen Dank im voraus !
Mit freundlichen Grüßen,
Thomas Tschofenig
-
sieht doch alles ganz gut aus.Bis auf das du ein T** m_Data hast. Mach da mal ein T* m_Data draus. Dann müsste es klappen.
Außerdem: Ich finds nich gut, bei jedem add speicher zu holen, der std::vector macht es zB so, dass er immer einen festen betrag speicher holt und nicht nur speicher für ein element.
-
data[count-1]=_data;Ich denke hier steckt der Fehler.
(Ich hab den code jetzt nur überflogen)Du weist einen const string ( den du per Referenz übergibts )
einem Array zu der Pointer auf strings erwartet!Du musst also entweder deine Definition von data ändern
(sodass er direkt strings speichert) oder aber selbst
speicher für einen neuen string anfordern, _data dorhineinkopieren
und dem Array data die adresse des neuen strings übergeben.
-
Hmm....also wenn ich es so abändere
T* data; //template <class T> void setCapacity(int cap) { cap=count; data = (T*)realloc(data,sizeof(T)*cap); }klappts mit dem Kompilieren zwar aber dafür wird dann bei der Speicherallokierung ein ungültiger Pointer allokiert.
@Storm.Xapek.de:
Entspricht das eigentlich nicht dem obrigen ?Danke erstmal !
Mfg.
Thomas
-
Okay, wenn ich gewusst hätte das die STL-Template-Klasse "Vector" genau das macht was ich hier versucht habe zu programmieren dann hätte ich wohl drauf verzichtet diesen Thread aufzumachen...
Danke trotzdem !
Thema (ungelöst) erledigt...
-
Maxi schrieb:
sieht doch alles ganz gut aus.Bis auf das du ein T** m_Data hast. Mach da mal ein T* m_Data draus. Dann müsste es klappen.
Außerdem: Ich finds nich gut, bei jedem add speicher zu holen, der std::vector macht es zB so, dass er immer einen festen betrag speicher holt und nicht nur speicher für ein element.
std::vector vergrössert den Speicher üblicherweise auf 150-200% von dem was er bereits "hat". Anders könnte die O(1) Garantie (amortisiert) für push_back auch nicht eingehalten werden. std::vector kann also garnicht einen "festen Betrag Speicher" holen wenn die Implementierung den Standard erfüllen möchte.
-
thomas233 schrieb:
//template <class T> void setCapacity(int cap) { cap=count; data = (T*)realloc(data,sizeof(T)*cap); }klappts mit dem Kompilieren zwar aber dafür wird dann bei der Speicherallokierung ein ungültiger Pointer allokiert.
Nochmal hierzu: Dass das schiefgeht ist kein Wunder, denn das geht nur in extrem wenigen Fällen gut (genau: Wenn T ein POD ist). Du holst hier Speicher für n Ts, aber für kein einziges Objekt wird der Konstruktor aufgerufen, damit sind alle Objekte in dem Speicherbereich unbrauchbar. Wenn T z.B. ein std::string ist, liegen dort lauter strings, die ungültige (zufällige) Verwaltungsinformationen enthalten. Wenn Du darauf zugreifen möchtest: BUMM.