Evolutionärer Algorithmus/Strukturen
-
Hallo!
Thx for your support! Aber ich hab da mal wieder ne Frage: Warum/Wofür brauche ich diesen Kopierkonstruktor überhaupt? Allgemein nimmt der Kopierkonstruktor eine Referenz auf ein Objekt desselben Typs als Parameter entgegen und hat die Aufgabe, eine Kopie des Objektes zu erstellen. Aber welche Bedeutung kommt ihm in Bezug auf Vektoren zu???
Brauche ich einen speziellen Kopierkonstruktor, oder reicht der Standardkopierkonstruktor, der ja doch vom Compiler scheinbar selbst angelegt wird? Oder reicht dieser nicht, weil er zu den "flachen" Kopierkonstruktoren zählt? Auf den Begriff flach/tief bin ich bei Wikipedia gestossen(http://de.wikipedia.org/wiki/Kopierkonstruktor). Es werden zwei Beispiele zu jeweils einer Art von Konstruktor gegeben. Mein Problem beim zweiten Bsp für den flachen Kopierkonstruktor ist, dass in meinen Augen auch hier eine echte Kopie erstellt wird, da mit new char[] ein separater Speicherbereich existiert.Dank im Voraus!
-
LoKi.aK schrieb:
Aber ich hab da mal wieder ne Frage: Warum/Wofür brauche ich diesen Kopierkonstruktor überhaupt? Allgemein nimmt der Kopierkonstruktor eine Referenz auf ein Objekt desselben Typs als Parameter entgegen und hat die Aufgabe, eine Kopie des Objektes zu erstellen. Aber welche Bedeutung kommt ihm in Bezug auf Vektoren zu???
Nehmen wir an, du hast irgendwelche Objekte, die du in den Container einfügen willst.
MyClass obj1, obj2;Nun willst du beim Einfügen, dass innerhalb des Containers eine Kopie gespeichert wird und du die Originale unabhängig davon weiter benutzen kannst. Also rufst du
push_back()auf, und der Container kopiert die Werte und speichert die Kopien. Die Originale bleiben unverändert.std::vector<MyClass> Vec; Vec.push_back(obj1); Vec.push_back(obj2);LoKi.aK schrieb:
Brauche ich einen speziellen Kopierkonstruktor, oder reicht der Standardkopierkonstruktor, der ja doch vom Compiler scheinbar selbst angelegt wird? Oder reicht dieser nicht, weil er zu den "flachen" Kopierkonstruktoren zählt? Auf den Begriff flach/tief bin ich bei Wikipedia gestossen(http://de.wikipedia.org/wiki/Kopierkonstruktor). Es werden zwei Beispiele zu jeweils einer Art von Konstruktor gegeben. Mein Problem beim zweiten Bsp für den flachen Kopierkonstruktor ist, dass in meinen Augen auch hier eine echte Kopie erstellt wird, da mit new char[] ein separater Speicherbereich existiert.
Der compilergenerierte Kopierkonstruktor (sowie auch der Zuweisungsoperator) kopiert Element für Element. Du musst dir überlegen, ob das für deine Klasse ausreicht. Hast du zum Beispiel einen Zeiger auf dynamisch allokierten Speicherbereich, so wird nur der Zeiger - und nicht der Speicherbereich - kopiert. Also musst du den Kopierkonstruktor selbst implementieren.
Sobald du Kopierkonstruktor, Zuweisungsoperator oder Destruktor selbst implementierst, musst du dich grundsätzlich auch um die anderen beiden kümmern (rule of the big three), damit dein Verhalten definiert bleibt.
-
Hi!
Hab nun meine Header-/Quelldatei wie folgt aufgesetzt:
class SingleRes { public: int x; int y; int pol; public: SingleRes(); SingleRes(const SingleRes& rhs); SingleRes& operator=(const SingleRes& rhs); ~SingleRes(); } #include "SingleRes.h" //using namespace std; //DefaultKonstruktor SingleRes::SingleRes() { x=0; y=0; pol=0; } //Kopierkonstruktor SingleRes::SingleRes(const SingleRes& rhs) { x=rhs.x; y=rhs.y; pol=rhs.pol; } //Operatorfunktion SingleRes& SingleRes::operator=(const SingleRes& rhs) { x=rhs.x; y=rhs.y; return *this; } //Destruktor SingleRes::~SingleRes(){}Eigentlich recht einfach, nur meckert mein Compiler:
12 C:\Users\LoKi.Ak\Desktop\StuffToday\C++\SingleRes.h expected;' before '~' token 3 C:\\Users\\LoKi.Ak\\Desktop\\StuffToday\\C++\\SingleRes.cpp expected unqualified-id before "using" 3 C:\\Users\\LoKi.Ak\\Desktop\\StuffToday\\C++\\SingleRes.cpp expected,' or;' before "using" 23 C:\\Users\\LoKi.Ak\\Desktop\\StuffToday\\C++\\SingleRes.cpp no \SingleRes& SingleRes::operator=(const SingleRes&)' member function declared in class `SingleRes'
30 C:\Users\LoKi.Ak\Desktop\StuffToday\C++\SingleRes.cpp no `SingleRes::~SingleRes()' member function declared in class `SingleRes'Erkennt jemand von Euch meinen Fehler?
Thx
-
Sicher, dass du alle nötigen Semikolons hast?

-
Nunja, hinter der Klasse habe ich noch ein Semikolon eingefügt, dass ändert aber leider auch nichts, die Fehlermeldung bleibt dieselbe. Was hat es überhaupt mit dem "expected unqualified-id before "using"" auf sich?
-
Hallo!
Ich hab nun nochmal Literatur gewälzt und die Methode des scharfen Hinsehens probiert, aber ich komme nicht dahinter, was bei mir falsch läuft. Vllt nimmt sich ja einer von Euch meiner an und wirft mal n Blick auf meinen code.
Zunächst die header-Datei:
class SingleRes { public: int x; int y; int pol; public: SingleRes(); ~SingleRes(); SingleRes(const SingleRes& rhs); SingleRes& operator=(const SingleRes& rhs); };Dann die Quelldatei:
#include "SingleRes.h" //DefaultKonstruktor SingleRes::SingleRes() { x=0; y=0; pol=0; } //Destruktor SingleRes::~SingleRes(){} //Kopierkonstruktor SingleRes::SingleRes(const SingleRes& rhs) { x=rhs.x; y=rhs.y; pol=rhs.pol; } //Operatorfunktion SingleRes& SingleRes::operator=(const SingleRes& rhs) { x=rhs.x; y=rhs.y; pol=rhs.pol; return *this; }Desweiteren soll in einer weiteren Klasse ein Vektor vom Typ der obigen Klasse deklariert(und somit auch definiert?) werden. Da die Elemente erst zur Laufzeit entstehen(und die Anzahl variiert), kann ich im Konstruktor nur einen Schätzwert über reserve() angeben. Seht Ihr bei meiner Konstruktion irgendwelche Gefahren auf mich zukommen? Hab ich den Kopierkonstruktor richtig aufgebaut?
headerDatei der zweiten Klasse:
#include <vector> class ResSet { public: int ResPos; int ResNeg; int ResSum; int Diff; vector<SingleRes> R; public: ResSet(); ~ResSet(); }Zu guter Letzt: es zeigt sich bei mir, dass ich ein und dieselbe Funktion in verschiedenen Klassen brauche. Muss ich die Funktion also mehrfach schreiben? Wahrscheinlich nicht. Löst man das Problem über Bibliotheken? Oder gliedert man die gemeinsam genutzten Funktionen aus-z.B. in eine Klasse MathOpera-und erzeugt in den jeweiligen Klassen Objekte dieser MathOpera-Klasse?
Ich hoffe, dass war jetzt nicht zuviel des Guten!!!
Dank im voraus!!!
-
Nur mal so am Rande:
http://shark-project.sourceforge.net/Gibts alles schon

//edit zu deinem Code:
Deine erste Klasse sieht in Ordnung aus. Allerdings muss ich dir mitteilen, dass bis auf den default-Konstruktor alle Methoden so sind, wie sie der Compiler auch automatisch erzeugen würde. Du brauchst sie also nicht.Ansonsten würde ich dir raten, die variablen private zu machen und dann mit get/set funktionen drauf zuzugreifen. Über das reserve beim vector solltest du dir keine Gedanken machen. Normalerweise kannst du es bedenkenlos ignorieren.
-
Hallo!
Sicher gibt es schon längst evolutionäre Algorithmen, denn noch möchte ich mich selbst auf dem Feld probieren. Einfach um ein paar Dinge nachvollziehen zu können.
Also, wenn mit meinem code alles soweit in Ordnung ist, warum spuckt der compiler die zuvor geposteten Fehlermeldungen aus?? Hab ich irgendein include vergessen? Am namespace kann es schliesslich auch nicht liegen.
Und inwieweit muss ich mir über das reserve keine gedanken machen? Ist es in Verbindung mit vectoren nicht ratsam die erwartete Kapazität anzugeben? Soweit ich weiss, nimmt das Erweitern des Vektors "viel" Zeit in Anspruch.
Gruss!!
-
Also, wenn mit meinem code alles soweit in Ordnung ist, warum spuckt der compiler die zuvor geposteten Fehlermeldungen aus?
Welchen Compiler nutzt du denn?
-
da fehlt ein semikolon am ende von
LoKi.aK schrieb:
headerDatei der zweiten Klasse:
-
Meine IDE ist WxDev, das ja standardmäßig mit MinGW als compiler kommt. Ja, da fehlt doch wirklich so ein drecks semikolon...ändert aber auch nichts an der Fehlermeldung.
-
LoKi.aK schrieb:
Und inwieweit muss ich mir über das reserve keine gedanken machen? Ist es in Verbindung mit vectoren nicht ratsam die erwartete Kapazität anzugeben? Soweit ich weiss, nimmt das Erweitern des Vektors "viel" Zeit in Anspruch.
Wenn du ungefähr weisst, wie viel Speicherplatz der
std::vectorbenötigt, istreserve()okay. Aber wenn du zuerst eine komplizierte Abschätzung durchführen musst, mit der du dann trotzdem in der Hälfte der Fälle falsch liegst, überlässt du die Speicherverwaltung lieber demstd::vector. Eine Reallokation dauert erst spürbar lange bei wirklich vielen bzw. grossen Elementen, dafür kannst du in einigen Fällen Speicherplatz sparen.
-
Da bei mir im worstcase 1024x1024 vectorelemente vom typ SingleRes möglich sind, dachte ich mir, lege ich im ersten Schritt 1/4 der Maximalmenge vor. Eine Reduzierung am Schluss auf die tatsächliche Kapazität sollte ja doch nicht kompliziert/aufwendig sein, da vectoren doch bei operationen auf die letzten elemente einen geringen(/konstanten) zeitaufwand haben!?!?
Könnten die Fehlermeldungen mit meinem compiler zusammenhängen? Inwiefern?
-
LoKi.aK schrieb:
Eine Reduzierung am Schluss auf die tatsächliche Kapazität sollte ja doch nicht kompliziert/aufwendig sein, da vectoren doch bei operationen auf die letzten elemente einen geringen(/konstanten) zeitaufwand haben!?!?
Nicht kompliziert, aber unmöglich. Ein
std::vectorgibt den angeforderten Speicher eigentlich erst im Destruktor wieder frei. Von daher solltest du vorsichtig sein mit präventiven Allokationen. Vielleicht besser, du überlässt das Speichermanagement demstd::vector.Und die Operationen auf dem letzten Element haben eine (amortisiert) konstante Zeitkomplexität, jedoch gehen darunter eigentlich keine Reallokationen. Diese tragen nur zum "amortisiert" bei, in den meisten Fällen sind sie nicht nötig. Aber du kannst auch keinen Speicherbereich verkleinern, ohne ihn neu anzulegen.
-
Ok, war der Meinung man könne mit erase den vector zu schluss anpassen. Dabei veränder ich aber nur die Anzahl der Elemente, nicht die Größe des allokierten Speichers.
Eine andre Frage, die wahrscheinlich in blutigste Anfängerkategorie gehört:
Ich habe in der Signatur(Übergabeparamter) zweier Funktionen zwei Variablen mit gleichem Namen deklariert, wobei die eine Funktion in der anderen aufgerufen wird. Soweit ich weiss, sind lokale Variable "gekapselt", d.h. die eine Variable in der inneren bekommt beim Durchlaufen ihrer Funktion nichts von der anderen in der äußeren Funktion mit. Oder kann es da doch zu Komplikationen kommen?Zuletzt noch eine ältere Frage:
Es geht darum, dass ich ein und dieselbe Funktion in verschiedenen Klassen brauche. Muss ich die Funktion also mehrfach schreiben? Wahrscheinlich nicht. Löst man das Problem über Bibliotheken? Oder gliedert man die gemeinsam genutzten Funktionen aus-z.B. in eine Klasse MathOpera-und erzeugt in den jeweiligen Klassen Objekte dieser MathOpera-Klasse?Sry, dass ich hier teilweise Anfängerfragen poste. Bin noch nicht lange dabei und bin bei vielem noch unsicher, da ich es nicht genau weiss!
Thx
-
Deklariere die Funktion einfach außerhalb einer Klasse in einem Header, und implementiere sie dann in einer cpp Datei. In C++ musst du nicht alles in Klassen stecken

-
LoKi.aK schrieb:
Ich habe in der Signatur(Übergabeparamter) zweier Funktionen zwei Variablen mit gleichem Namen deklariert, wobei die eine Funktion in der anderen aufgerufen wird.
Sofern die Variablen in unterschiedlichen Scopes deklariert wurden (im gleichen Scope ist gar nicht möglich), benutzt du automatisch die des innersten Gültigkeitsbereiches, also quasi die lokalste. Innerhalb einer Funktion sind nur Parameter, globale und lokale Variablen bekannt - nicht aber die aus anderen Scopes.
LoKi.aK schrieb:
Es geht darum, dass ich ein und dieselbe Funktion in verschiedenen Klassen brauche. Muss ich die Funktion also mehrfach schreiben?
Nein. Mehrfach schreiben solltest du grundsätzlich nichts. Implementiere die Funktion wie von otze erwähnt als freie Funktion, eventuell in einem eigenen Namensraum. Es hat keinen Sinn, eine Klasse "MathOpera" zu erzeugen, die nur ein paar Funktionen zusammenfasst. Da machst du lieber einen
namespace.