Vektor Klasse selbst geschrieben...
-
Hi,
ich hab eine klasse Vektor geschrieben, die aber irgendwie nicht richtig funktioniert. ich möchte, dass man mit auf die Vektorelemente mit [] zugreifen kann. Also: Vektor v = new Vektor(2); v[1]=2; (siehe main unten)
class Vektor{ private: int rows; string name; void init(); double* values; public: Vektor(int rows); string getName(); void setName(string name); int getRows(); double& operator[] (int row); Vektor operator* (Vektor V); }; Vektor::Vektor(int rows){ this->rows=rows; this->values=new double[rows]; this->init(); } double& Vektor::operator[] (int row){ if(row<0 || row > this->rows) exit(1); else return this->values[row]; } void Vektor::init(){ for(int i=0; i<rows; i++){ this->values[i]=0; } } int main(void){ Vektor * v=new Vektor(3); v[2]=34; cout << v[2]; return 0; }ich bekomme die fehlermeldung des compilers, dass v[2] ein vektor. ich frag mich nur warum das so ist, denn v[2] sollte eigentlich ein double sein. jemand eine ahnung?
-
...v ist ein Pointer. Schreib
Vektor v(3);Im Übrigen leckt deine Vektorklasse Speicher, du solltest das, was du mit new[] angelegt hast, im Destruktor wieder delete[]n.
-
naja, das wollte ich ja grade nicht, weil ich dynamisch also während der Laufzeit den Vektor erstellen werde und die größe noch nicht feststeht... deshalb wollte ich schon mit Vektor *v = new Vektor(3) arbeiten.
-
Du kannst dem Konstruktor locker ne Variable übergeben:
int x; std::cout << "Zahl: " << std::flush; std::cin >> x; Vektor v(x);...gar kein Problem. Ansonsten, wenns unbedingt auf den Heap soll, dann musst du später den Zeiger dereferenzieren, bevor du den Operator benutzt, also
(*v)[2] = 34;...und vergiss dann nicht, den Vektor nachher wieder zu deleten, sonst kriegst du Speicherlecks.
-
Ok, danke erstmal für deine Hilfe!
class A{ public: Vektor v; A(int size); }; A::A(int size){ v(size); }der code spiegelt vielleicht mein problem besser wieder...
A soll einen Vektor v haben, dessen größe jedoch erst während der Laufzeit bekannt wird... so funktioniert das aber leider nicht.ich weiß, dass folgende Lösung funktioniert:
A::A(int size):v(size){ }aber das kanns ja nicht sein... in meinem programm hätte ich dann hinter dem doppelpunkt ne menge objekte stehen, die alle während der laufzeit initialisiert werden.
Gibts hier ne elegantere Lösung?
-
mach nen default c-tor in deine vector klasse der die size mit 0 initialisiert und den ptr fuer daten auf 0 stellt.
-
Ok, das haut hin. Danke für den Tip.
Das ganze ist aber dann doch noch nicht gegessen, weil ich im Grunde folgendes habe:
/*Klasse Vektor*/ class Vektor{ private: int rows; string name; void init(); double* values; public: Vektor(string name, int rows); Vektor(); ~Vektor(); string getName(); void setName(string name); int getRows(); double& operator[] (int row); }; /*Klasse Matrix*/ class Matrix{ private: Vektor *matrix; void init(); int columns; int rows; public: Matrix(); ~Matrix(); Matrix(int columns, int rows); Vektor& operator[](int column); int getrows(); int getcolumns(); }; /*Implementierung Vektor*/ Vektor::Vektor(string name, int rows){ this->rows=rows; this->name=name; this->values=new double[rows]; this->init(); } Vektor::Vektor(){ this->rows=0; this->values=0; this->name=""; } double& Vektor::operator[] (int row){ if(row<0 || row > this->rows) exit(1); else return this->values[row]; } /*Implementierung Matrix*/ Matrix::Matrix(int columns, int rows){ this->columns=columns; this->rows=rows; this->init(); matrix=new Vektor[columns]; } Vektor& Matrix::operator[](int column){ if(column<0 || column > (this->columns-1)) exit(1); else return (*this)[column]; } void Matrix::init(){ for(int i=0; i<columns; i++){ for(int j=0; j<rows; j++){ matrix[i][j]=0; //matrix[i]=Vektor(rows); } } }Naja, ich hab also eine Matrix, die sich aus Spaltenvektoren zusammensetzt... mit matrix[i][j] möchte ich dann auf die double werte zurückgreifen und mit matrix[i] auf den spaltenvektor. das funktioniert aber alles nicht so, wie ich mir das vorgestellt habe... Matrix::init() soll einfach nur die Matrix mit Nullen füllen, macht sie aber nicht.
-
Öh, aber genau dafür ist die Initialisierungsliste ja da. Ich seh auch nicht, wie
A::A(int a, int b, int c) : a_(a), b_(b), c_(c) { // ... }schlimmer ist als
A::A(int a, int b, int c) { a_ = a; b_ = b; c_ = c; }Davon ganz abgesehen sparst du dir damit im Vergleich zum Anlegen auf dem Heap nachher im Destruktor ein delete, also wird dein Code noch kürzer. Wo ist das Problem?
-
Ansonsten, schreib halt ne expand-Funktion oder so.
class Vektor { // ... public: // ... void expand(std::size_t new_size); } // Für std::copy und std::fill #include <algorithm> void Vektor::expand(std::size_t new_size) { std::size_t old_size = rows; if(new_size <= old_size) return; double *old = values; values = new double[new_size]; std::copy(old, old + old_size, values); std::fill(values + old_size, values + new_size, 0.0); rows = new_size; delete[] old; } // ... Matrix::Matrix(std::size_t columns, std::size_t rows) : columns(columns), rows (rows) { Matrix = new Vektor[columns]; for(int i = 0; i < columns; ++i) Matrix[i].expand(rows); }