CArray Class, mach ichs richtig?
-
krümelkacker schrieb:
- Das Array weiß nie, wie groß es ist
- Du hast die Dreierregel verletzt (kann man nach googeln)Ok hab size hinzugefügt, und den fehler im memcpy denke ich auch gefixed, sollte man jetzt auch verkleinern koennen.
CArray.h
#ifndef _CARRAY_H_ #define _CARRAY_H_ class CArray { public: CArray(void); CArray(int iSize); ~CArray(void); bool ReSize(int iSize); int *arr; int size; }; #endifCArray.cpp
#include <exception> #include <string.h> #include "CArray.h" using namespace std; CArray::CArray(int iSize) { try { arr = new int[iSize]; } catch (bad_alloc&) { } size = iSize; } CArray::~CArray(void) { delete[] arr; } bool CArray::ReSize(int iSize) { int *tmp; try { tmp = new int[iSize]; } catch (bad_alloc&) { return false; } memcpy(tmp, arr, size * sizeof(int)); delete[] arr; arr = tmp; size = iSize; return true; }main.cpp
#include <iostream> #include "CArray.h" using namespace std; int main(void) { CArray atest(20); atest.arr[19] = 222; printf("%d %d\n",atest.arr[19], atest.size); atest.ReSize(30); printf("%d %d\n",atest.arr[19], atest.size); return 0; }
-
krümelkacker schrieb:
- Das Array weiß nie, wie groß es ist
- Du hast die Dreierregel verletzt (kann man nach googeln)Die Dreierregel, auch bekannt als Die Große Drei oder Regel der Großen Drei bezeichnet in C++ eine Daumenregel, die besagt, dass, wenn eine Klasse eines der folgenden drei definiert, meistens auch die anderen beiden definiert werden sollten[1]:
Kopierkonstruktor
Destruktor
ZuweisungsoperatorWas fehlt mir ?
-
Du hast keinen Kopierkonstruktor und keinen Zuweisungsoperator definiert. Wenn Du zB ein Objekt Deiner Klasse per value-Übergabe an eine Funktion übergibst, wird eine flache Kopie erstellt, dh der arr-Zeiger der Kopie zeigt auf denselben Speicher, wie der des Originals. Beim Beenden der Funktion wird die Kopie zerstört, der Destruktor wird aufgerufen und gibt den Speicher, auf den arr zeigt, frei. Nun hat zeigt arr im Original - Objekt auf Speicher, der Dir nicht mehr gehört.
-
cutiepie666 schrieb:
CArray.h
#ifndef _CARRAY_H_ #define _CARRAY_H_ class CArray { public: CArray(void); CArray(int iSize); ~CArray(void); bool ReSize(int iSize); int *arr; int size; }; #endif- Bestimmte Bezeichner sind reserviert. Dein Include-Guard ist ein solcher reservierter Bezeichner.
- Warum sind arr und size öffentlich?
- Statt "(void)" schreibt man in C++ "()".
- Kopierkonstruktor und Zuweisungsoperator werden hier vom Compiler selbst deklariert und ggf definiert (bei Benutzung). Diese tun dann aber das falsche (Kopieren einfach den Zeiger). So kannst Du ein CArray-Objekt kopieren. Beide Objekte zeigen dann aber auf denselben Speicherbereich und fühlen sich als alleinigen Besitzer. Es kommt zu einer Doppellöschung oder einem Speicherleck.cutiepie666 schrieb:
CArray.cpp
#include <exception> #include <string.h> #include "CArray.h" using namespace std; CArray::CArray(int iSize) { try { arr = new int[iSize]; } catch (bad_alloc&) { } size = iSize; } CArray::~CArray(void) { delete[] arr; } bool CArray::ReSize(int iSize) { int *tmp; try { tmp = new int[iSize]; } catch (bad_alloc&) { return false; } memcpy(tmp, arr, size * sizeof(int)); delete[] arr; arr = tmp; size = iSize; return true; }- eine bad_alloc-Ausnahme solltest Du nicht dort im Konstruktor fangen. Wenn die fliegt, bleibt "arr" ungültig, das Objekt lebt, ist aber nicht benutzbar. Besser ist es, die Ausnahme einfach weiter fliegen zu lassen. Dann muss man als Anwender von CArray auch nicht extra prüfen, ob der Konstruktor seinen Job erledigt hat oder nicht. Gleiches gilt für ReSize. Entweder ReSize funktioniert oder es fliegt eine Ausnahme. Keine Grund noch einen bool zurück zu geben!
- Die Zahl der zu kopierenden Objekte in ReSize ist min(alte_groesse,neue_groesse), nicht alte_groesseSchaff Dir bitte vernünftiges Lehrmaterial für C++ an. Ich kann persönlich empfehlen:
- Accelerated C++
- Effective C++Positives Beispiel:
intarray.h
#ifndef INTARRAY_H_INCLUDED #define INTARRAY_H_INCLUDED #include <algorithm> #include <cassert> class intarray { int* ptr_; int size_; public: intarray() : ptr_(0), size_(0) {} explicit intarray(int size); // Destruktor ~intarray(); void swap(intarray & with) { using std::swap; swap(this->ptr_, with.ptr_); swap(this->size_, with.size_); } // Kopierkonstruktor intarray(intarray const&); // Zuweisungsoperator intarray& operator=(intarray temp) { this->swap(temp); return *this; } int size() const {return size_;} int const* get() const {return ptr_;} int * get() {return ptr_;} int const& operator[](int index) const { assert(ptr_); assert(0<=index && index<size_); return ptr_[index]; } int & operator[](int index) { assert(ptr_); assert(0<=index && index<size_); return ptr_[index]; } }; inline void swap(intarray & a, intarray & b) { a.swap(b); } #endifintarray.cpp
#include <algorithm> #include "intarray.hpp" intarray::intarray(int size) : ptr_(new int[size]), size_(size) {} intarray::~intarray() { delete[] ptr_; } intarray::intarray(intarray const& x) : ptr_(0), size_(0) { if (x.ptr_ && x.size_>0) { ptr_ = new int[x.size_]; size_ = x.size_; std::copy(x.ptr_,x.ptr_+x.size_,ptr_); } }(bugfixing and a resize function is left to the reader)
Natürlich ist diese Klasse nur zu Demonstrationszwekcen/zur Übung und man sollte stattdessen so etwas wie std::vector verwenden. In Büchern wir Accelerated C++ verwendet man zunächst für die Lösung von einfachen Problemen Standardcontainer, IOstreams und die String-Klasse. In späteren Kapiel wird dann erklärt, wie man sich eigene Typen bauen kann, die ähnlich einfach zu benutzen sind...
-
Sag mal, wieso nimmst du C-I/Os ?
Dein Programm dürfte garnicht kompilieren. Für printf musst du <cstdio> einbinden, wobei ich <iostream> gleich lasssen würde und wie alle normalen Menschen 'cout' benutzen würd'.
Das 'void' inmain(void)ist auch unnötig, ebenso wie das
return 0;Edit: Zu spät ...
-
-
Schaff Dir bitte vernünftiges Lehrmaterial für C++ an. Ich kann persönlich empfehlen:
- Accelerated C++
- Effective C++Danke fuer die Hilfe, klingt alles einleuchtend, wuerde mir ja gerne diese 2 buehcer besorgen, jedoch hab ich keine lust auf papier, und als ebook versionen zum kauf find ich beide leider nicht, da beide von 2000 sind, gibts nichts aktuelleres, veroeffentlich kuerzlich was genauso gut ist damit ich es als ebook kaufen kann?
-
Mir sind leider keine offiziellen eBooks mit ähnlich hoher Qualität bekannt.
Aktuell genug sind die vorgeschlagenen Bücher aber.
-
Wenn du mir ein Email schreibst, kann ich dir Effective C++ als EBook zukommen lassen. Allerdings werde ich in den nächsten Tagen nicht so schnell antworten.
-
314159265358979 schrieb:
Wenn du mir ein Email schreibst, kann ich dir Effective C++ als EBook zukommen lassen. Allerdings werde ich in den nächsten Tagen nicht so schnell antworten.
Na, wenn er solche Quellen will, dann findet man beide in 5 Sekunden bei Google.
P.S.: Und es beweist natürlich, dass die Ebooks existieren.
-
Ich habs noch nicht gegoogelt, das kann schon sein.
-
314159265358979 schrieb:
Ich habs noch nicht gegoogelt, das kann schon sein.
Ich schon.

-
SeppJ schrieb:
P.S.: Und es beweist natürlich, dass die Ebooks existieren.
Es beweist nicht, dass es die Titel als legal kaufbare eBooks gibt. Die kann ja auch jemand eingescannt oder abgetippt haben...
Und gebraucht bekommt man die Bücher wahrscheinlich für weniger als 20€ (jeweils). Das sind sie allemal Wert, wenn man berücksichtigt, dass man sich damit viel Zeit und Ärger sparen kann...
OT: Was mir bei geDRMten eBooks allerdings fehlt, ist die Möglichkeit, Bücher zu verleihen, verschenken, verkaufen. Da mann nur die Lese-Lizenz erwirbt, sind sie wenigstens oft günstiger. (Das sage ich als "Kindle Keyboard"-Besitzer)
