[c++] gleichnamiges Objekt unterschiedlicher Klassen mit Auswahl erstellen
-
Wenn ich den Code wie folgt anwende:
GAGeneticAlgorithm* ga = NULL; cout << "Klasse 1 o. 2? "; int class_type(0); std::cin >> class_type; if (class_type == 1) ga = new GASimpleGA; else ga = new GASteadyGA;kommt folgender Fehler:
no matching function for call to `GASimpleGA:: GASimpleGA()'GAGeneticAlgorithm ist Basisklasse und GASimpleGA, GASteadyGA sind abgeleitet Klassen. Alle Klassen existieren in einer externen Bibliothek auf die ich zugreife.
-
no matching function for call to `GASimpleGA::
GASimpleGA()'das heißt einfach nur das es für diese Klasse keinen Defaultconstruktor gibt... du musst beim Konstruieren des Objekts also die Paramater die erforderlich sind mit angeben
-
Hallo,
das zu übergebende Argument ist ein Objekt namens genome
GABin2DecGenome genome(map, objective);Wenn ich es wie folght einbinde:
GAGeneticAlgorithm ga(genome) = NULL; cout << "Klasse 1 o. 2? "; int class_type(0); std::cin >> class_type; if (class_type == 1) ga(genome) = new GASimpleGA; else ga(genome) = new GASteadyGA;beklomme ich diese Fehler:
Optimierer.C:214: error: cannot declare variable `ga' to be of type ` GAGeneticAlgorithm' Optimierer.C:214: error: because the following virtual functions are abstract: /smb_mnt/tgutjahr/p/groupdrives/oe624-lsk/Aktuell/dipl/08-gutjahr/programme/Optimierungsprogramm/Galib/galib247/include/ga/GABaseGA.h:133: error: virtual void GAGeneticAlgorithm::initialize(unsigned int) /smb_mnt/tgutjahr/p/groupdrives/oe624-lsk/Aktuell/dipl/08-gutjahr/programme/Optimierungsprogramm/Galib/galib247/include/ga/GABaseGA.h:134: error: virtual void GAGeneticAlgorithm::step() Optimierer.C:214: error: assignment (not initialization) in declaration Optimierer.C:218: error: no match for call to `(GAGeneticAlgorithm) ( GABin2DecGenome&)' Optimierer.C:218: error: no matching function for call to `GASimpleGA:: GASimpleGA()' /smb_mnt/tgutjahr/p/groupdrives/oe624-lsk/Aktuell/dipl/08-gutjahr/programme/Optimierungsprogramm/Galib/galib247/include/ga/GASimpleGA.h:24: error: candidates are: GASimpleGA::GASimpleGA(const GASimpleGA&) /smb_mnt/tgutjahr/p/groupdrives/oe624-lsk/Aktuell/dipl/08-gutjahr/programme/Optimierungsprogramm/Galib/galib247/include/ga/GASimpleGA.h:23: error: GASimpleGA::GASimpleGA(const GAPopulation&) /smb_mnt/tgutjahr/p/groupdrives/oe624-lsk/Aktuell/dipl/08-gutjahr/programme/Optimierungsprogramm/Galib/galib247/include/ga/GASimpleGA.h:22: error: GASimpleGA::GASimpleGA(const GAGenome&) Optimierer.C:219: error: no match for call to `(GAGeneticAlgorithm) ( GABin2DecGenome&)'Was ist hier schief gelaufen??
Grüße
Guddy
-
Du machst grundsätzlich was falsch. Du hast die Klassen auch nicht geschrieben, oder?
Ohne deren Signaturen kann ich dir da auch nicht weiterhelfen.
-
nein, die habe ich nicht geschrieben.
GABin2Dec hat folgenden Code:
#ifndef _ga_bin2dec_h_ #define _ga_bin2dec_h_ #include <ga/GA1DBinStrGenome.h> #include <ga/gabincvt.h> #ifdef max #undef max #endif #ifdef min #undef min #endif class GABin2DecPhenotypeCore { public: GABin2DecPhenotypeCore(); GABin2DecPhenotypeCore(const GABin2DecPhenotypeCore&); virtual ~GABin2DecPhenotypeCore(); GABin2DecPhenotypeCore& operator=(const GABin2DecPhenotypeCore&); unsigned int cnt; // how many references to us? unsigned int csz; // how big are the chunks we allocate? unsigned int n, N; // how many phenotypes do we have? (real,alloc) unsigned short *nbits; // number of bits that max/min get mapped into unsigned short *oset; // offset of the nth gene float *minval, *maxval; // min, max value of phenotype elem unsigned int sz; // total number of bits required }; class GABin2DecPhenotype { public: GABin2DecPhenotype() : core(new GABin2DecPhenotypeCore) {} GABin2DecPhenotype(const GABin2DecPhenotype& p) : core(new GABin2DecPhenotypeCore(*(p.core))) {} virtual ~GABin2DecPhenotype(){core->cnt -= 1; if(core->cnt==0){delete core;}} GABin2DecPhenotype & operator=(const GABin2DecPhenotype& p){ if(&p != this) *core = *(p.core); return *this; } GABin2DecPhenotype * clone() const {return new GABin2DecPhenotype(*this);} void link(GABin2DecPhenotype& p){ core->cnt -= 1; if(core->cnt == 0) delete core; core=p.core; core->cnt += 1; } void add(unsigned int nbits, float min, float max); void remove(unsigned int which); unsigned int size() const {return core->sz;} unsigned int nPhenotypes() const {return core->n;} float min(int which) const {return core->minval[which];} float max(int which) const {return core->maxval[which];} int length(int which) const {return core->nbits[which];} int offset(int which) const {return core->oset[which];} int equal(const GABin2DecPhenotype&) const; protected: GABin2DecPhenotypeCore *core; }; inline int operator==(const GABin2DecPhenotype& a, const GABin2DecPhenotype& b) { return a.equal(b); } inline int operator!=(const GABin2DecPhenotype& a, const GABin2DecPhenotype& b) { return (a.equal(b) ? 0 : 1); } /* ---------------------------------------------------------------------------- The phenotype does reference counting, so we can make a copy of it for our own use and we don't have to worry about extra overhead. ---------------------------------------------------------------------------- */ class GABin2DecGenome : public GA1DBinaryStringGenome { public: GADefineIdentity("GABin2DecGenome", GAID::Bin2DecGenome); public: GABin2DecGenome(const GABin2DecPhenotype & p, GAGenome::Evaluator f=(GAGenome::Evaluator)0, void * u=(void *)0) : GA1DBinaryStringGenome(p.size(), f, u), ptype(new GABin2DecPhenotype(p)){ comparator(DEFAULT_BIN2DEC_COMPARATOR); encoder(DEFAULT_BIN2DEC_ENCODER); decoder(DEFAULT_BIN2DEC_DECODER); } GABin2DecGenome(const GABin2DecGenome & orig) : GA1DBinaryStringGenome(orig.sz) {ptype=(GABin2DecPhenotype *)0; copy(orig);} GABin2DecGenome& operator=(const GAGenome& arg) {copy(arg); return *this;} virtual ~GABin2DecGenome(){delete ptype;} virtual GAGenome *clone(GAGenome::CloneMethod flag=CONTENTS) const ; virtual void copy(const GAGenome &); #ifdef GALIB_USE_STREAMS virtual int read (STD_ISTREAM &); virtual int write (STD_OSTREAM &) const; #endif virtual int equal(const GAGenome &) const; virtual int notequal(const GAGenome &) const; const GABin2DecPhenotype & phenotypes(const GABin2DecPhenotype & p); const GABin2DecPhenotype & phenotypes() const {return *ptype;} int nPhenotypes() const {return ptype->nPhenotypes();} float phenotype(unsigned int n, float val); float phenotype(unsigned int n) const; void encoder(GABinaryEncoder e){encode = e; _evaluated = gaFalse;} void decoder(GABinaryDecoder d){decode = d; _evaluated = gaFalse;} protected: GABin2DecPhenotype * ptype; GABinaryEncoder encode; // function we use to encode the bits GABinaryDecoder decode; // function we use to decode the bits }; #endifden Code der GAGeneticAlgorithm- klasse hab ich leider nicht.
-
guddy schrieb:
GAGeneticAlgorithm ga(genome) = NULL;Kannst du uns erzählen, was du mit dieser Zeile erreichen willst? Ganz ehrlich, wenn man das mit deinen vorherigen Posts vergleicht, ergibt sich der Eindruck, dass du versuchst Codefetzen zusammenzustückeln die du nichtmal im Ansatz verstehst.
-
Mir ist schon klar das ich nicht alles verstehe was in den einzelenen Klassen der Bibliothek steht die ich hier benutze. Aber muss ich das?
Mein Programm, dass ich auf Grundlage der Bibliothek programmiert habe funktioniert bis jetzt tadellos. Nun möchte einfach eine Abfrage einbauen die mir die einfache Auswahl des Algorithmusobjektes ga ermöglicht.
Es gibt hier zwei Algorithmenklassen, die sich beide aus der Basisklasse GAGeneticAlgortihm ableiten und zwar GASimpleGA und GASteadystateGA. die Constructors, die ich verwenden will sind : GASimpleGA (const GAGenome&) und GASteadyStateGA(GAGenome&). das zu erzeugende Algorithmusobjekt ga kann nun
entweder der Klasse GASimpleGA oder GASteaadyGA angehören.
Ich möchte als Argument dem Objekt ga das Objekt genome übergeben, welches der Klasse GABin2DecGenome (Hierachie ist : public GA1DStringGenome : public GABinaryString, public GAGenome) angehört. Diese Objekt genome habe ich vorher erzeugt. Der Sinn der Geschichte ist, dass ich alle folgenden public Funktionen der GAGeneticAlgorithm-Klasse mit dem Objekt ga nutzen will. Und das ohne den Code nochmal neu zu schreiben. Beispiel:ga.parameters (params); //Parameterliste initialisieren ga.maximize(); //Minimiere die Zielfunktion ga.selectScores(GAStatistics::AllScores); // aufrufen aller Statistiken in neu erzeugteen Statistikobjekten /*Abfrage: startpop. einlesen? nein: ga.initialize. else: init pop*/ /*anstatt des ga initialisierer den pop-initialisierer verwenden um startpopulation einzulesen? */ //Ga-Objekt initialisieren ga.initialize (); //generiert die Ind. der 1. Gen.Ich hoffe das Problem ist jetzt etwas verständlicher formuliert.
@pumuckl: mit dem code
GAGeneticAlgorithm ga(genome) = NULL;wollte ich dem erzeugten Objekt den Wert Null zuweisen. ICh dachte ich wende den Code von Fellhuhn richtig an, tu ich aber anscheinend nicht.
Ich bin auf jeden Fall noch Anfänger auf dem Gebiet...
Grüße
Guddy
-
guddy schrieb:
Es gibt hier zwei Algorithmenklassen, die sich beide aus der Basisklasse GAGeneticAlgortihm ableiten und zwar GASimpleGA und GASteadystateGA. die Constructors, die ich verwenden will sind : GASimpleGA (const GAGenome&) und GASteadyStateGA(GAGenome&). das zu erzeugende Algorithmusobjekt ga kann nun
entweder der Klasse GASimpleGA oder GASteaadyGA angehören.
Ich möchte als Argument dem Objekt ga das Objekt genome übergeben, welches der Klasse GABin2DecGenome (Hierachie ist : public GA1DStringGenome : public GABinaryString, public GAGenome) angehört.GAGeneticAlgortihm *ga = NULL; if (wasauchimmer == 1) ga = new GASimpleGA(genome); else ga = new GASteadyStateGA(genome); ga->wasauchimmer(); // ... delete ga;
-
guddy schrieb:
Mir ist schon klar das ich nicht alles verstehe was in den einzelenen Klassen der Bibliothek steht die ich hier benutze. Aber muss ich das?
Wenn du die Klassen so nutzt, wie sie sind, und nicht mehr veränderst, reicht es, wenn du weisst, was die Methoden machen. Du musst dazu nicht zwingend die interne Implementation kennen. Wenn du allerdings die Funktionen dieser Klassen erweitern willst (z.B. durch Vererbung), solltest du schon Bescheid über die Implementationen wissen.
guddy schrieb:
Ich bin auf jeden Fall noch Anfänger auf dem Gebiet...
Dann empfehle ich dir, dich zuerst richtig in Klassen und Objektorientierung einzuarbeiten, bevor du mit Dingen wie genetischen Algorithmen arbeitest.
Du kannst nämlich nicht einfach einer Instanz von
GAGeneticAlgorithmeinen Wert wieNULLzuweisen. Wenn schon, dann einem Zeiger. Mit solchen Dingen solltest du dich unbedingt noch genauer auseinandersetzen, sonst wirst du dauernd wieder auf Probleme stossen.
-
Super. Das funktioniert so wie ichs mir erhofft hatte. ICh danke allen für ihre mühe.
Viele Grüße
Guddy
-
guddy schrieb:
Mir ist schon klar das ich nicht alles verstehe was in den einzelenen Klassen der Bibliothek steht die ich hier benutze. Aber muss ich das?
Der Code den du gepostet hast war eine Deklaration einer Variable ga, deren Konstruktor du ein Objekt genome übergeben hast und gleichzeitig eine Zuweisung mit NULL. Später hast du (zumindest sieht der Code so aus) eine Funktion ga aufgerufen, der du wiederum das selbe Objket genome als Argument verpasst hast und hast dem Ergebnis dieser Funktion einen Wert zugewiesen. Okay, man kann es auch als aufruf des operator() auf ga interpretieren, dann hast du wenigstens keine Zuweisung an ein temporäres Objket.
Alles in allem ist das aber schon aus C++-Sicht ziemlicher Humbug, da braucht man kein Verständnis der verwendeten Klassen zu haben. Mein Tip ist daher: setz dich mit den Sprachmitteln von C++ auseinander, damit du geposteten Code zumindest von der Semantik her verstehst und entsprechend umformen kannst um ihn selbst anzuwenden. Dass Copy&Paste-Kauderwelsch vom Compiler verstanden wird ist höchst unwahrscheinlich, dass es das tut was du möchtest erst recht

/edit: "dem erzeugten Objekt den Wert NULL zuweisen" - ein erster Ansatzpunkt wäre auf jeden Fall schonma, den unterschied zwischen Zeigern und Objekten kennezulernen
