Problem Faktorisierung Klassen
-
Zuerst mal einen schönen guten Morgen ins Forum!
Ich habe ein Problem. Und zwar bin ich ziemlicher C++ Anfänger und will jetzt eine knifflige Case Anweisung programmieren:
State of the Art:
Was will ich?
Ich bekomme einen int Wert mit dem Namen AlgoId rein und will jetzt sagen, welchen Algorithmus er aufrufen soll. Das geht doch am Besten mit einer Case Anweisung, oder?
Allerdings weiß ich nicht so ganz, wie ich dann die Algos aufrufe.Vielleicht zur Verdeutlichung meinen Code:
1. .h File
#ifndef algorithm_h_included #define algorithm_h_included #include <stdio.h> #include <iostream> #include <string> class Algorithm{ public: algorithm(); Algorithm algoId(int); void type (int); virtual bool identify ()=0; void storeResult (int Res [2][1]]; virtual ~algorithm(); }; class Aaa: public Algorithm { public: aaa( type = Aaa); // ?????????? Konstruktormit Type? bool identify(); virtual ~aaa(); private: ... }; class Bbb: public Algorithm { public: bbb(type = Bbb); bool identify(); virtual ~bbb(); private: ... }; class Ccc: public Algorithm { public: ccc(type = Ccc); bool identify(); virtual ~ccc(); private: ... }; #endif2. .cpp File
#include "Algorithm.h" #define Aaa= 0; #define Bbb= 1; #define Ccc= 2; algorithm::algorithm() {} Aaa:algorithm(){}; Bbb::algorithm(){}; Ccc::algorithm(){}; Algorithm Init (int algoID){ switch (algoId) { case 0: algo = new algorithm (Aaa); break; case 1: algo = new algorithm (Bbb); break; case 2: algo = new algorithm (Ccc); break; return algo; } algorithm::~algorithm() {}Macht das so Sinn????
Das AlgoId bekomme ich aus einer anderen Klasse in einem anderen Projekt...Danke!
-
Nein, das macht wenig Sinn - schau dir nochmal genauer an, wie man mit virtuellen Klassen umgehen sollte:
class algo { public: algo(); virtual void calc(int data)=0; virtual ~algo(); }; class Aaa : public algo { public: Aaa(...); void calc(int data); ~Aaa(); }; class Bbb : public algo { //analog zu Aaa }; enum{aaa,bbb,...} algo_type; algo* init(algo_type t) { switch(t) { case aaa:return new Aaa(...); case bbb:return new Bbb(...); ... default: return NULL; } }(oder du googlest mal nach "virtueller Konstruktor")
-
Danke.... Ich bekomme ja die AlgoId extern rein. Die ist entweder 0,1, oder 2.
Muss ich dann trotzdem noch das Enum definieren? Wenn ja wo? im Header?
Danke
-
Noch ne Frage: meine Funktion calc(int data) data ist doch dann eigentlich das was übergeben wird, das, was ich berechnen will?
Will ich meine Funktion calc jetzt mit dem Algorithmus aufrufen, der bei der Switsch/Case Anweidung rauskam, mache ich das wie?
Aaa.calc(int data) ????
-
Das enum ist eleganter wie deine defines. Du musst zudem jetzt nicht mehr immer nachsehen um welche Zahl es sich handelt um einen bestimmten Typ zu erhalten. Du übergibst der Variablen vom Typ algo_type einfach aaa, bbb, ... Letztendlich sind das auch nur Zahlen. In deinem Fall ist aaa=0, bbb=1 usw. Dafür aber wesentlich eleganter.
Ja, die enum-Definition kannst du in den Header packen, damit ihn auch jeder Benutzen kann.
-
Alex179 schrieb:
Noch ne Frage: meine Funktion calc(int data) data ist doch dann eigentlich das was übergeben wird, das, was ich berechnen will?
Will ich meine Funktion calc jetzt mit dem Algorithmus aufrufen, der bei der Switsch/Case Anweidung rauskam, mache ich das wie?
Aaa.calc(int data) ????
Du bekommst von der Funktion (s. die Funktion von CStoll) einen Zeiger zurück und dann greifst du mit dem Pfeiloperator auf die Funktion zur Berechnung zu, es wird automatisch die richtige verwendet:
algo* ptr = init(aaa); prt->calc(data); // data wurde zuvor irgendwo definiertHier wird das calc von aaa aufgerufen.
-
Alex179 schrieb:
Will ich meine Funktion calc jetzt mit dem Algorithmus aufrufen, der bei der Switsch/Case Anweidung rauskam, mache ich das wie?
Aaa.calc(int data) ????
Fast:
int main() { algo_type typ=...; algo* my_algo = init(typ); my_algo->calc(4711); }
-
Irgendwie funktiuoniert das immmernoch nicht richtig...
Nehmen wir an ich setze die algoId auf 1.Rufe dann extern auf:
Algo* algo = init (algoID); algo->identify (img);Und ich habe in meinem Header:
class Algo{ public: Algo(); void init(int algoID); virtual bool identify (int data)=0; virtual ~Algo(); };in der cpp den switch:
enum{yuv,nccf,sift} algoID; Algo* init(algoId) { switch(algoID) { case 0:return new YUV(); break; case 1:return new NCCF(); break; case 2:return new SIFT(); break; default: return NULL; } } ;Aber wieso gibt er mir Fehler, dass Klammern fehlen und und und?
Danke
-
Dein algoID enum is in der cpp definiert ?
die Algo klasse selber braucht die algo ID definition aber auch ! oder ? (hat ja schliesslich nen parameter.
da die Algo ID zu deiner Algo klasse im logischen sinne gehoert, wuerd ich die ID in die Klasse stecken ....
init ist eine Methode an der Algo klasse, aufrufen tust die aber ohne Instanz ?
Algo* algo = init (algoID); Sollte nicht gehen, weil er die init methode nicht finden sollte ...
Dein init gehoert aber logisch genau so zu deiner Algo klasse -> typischer einsatzfall von statischen memberfunktionen !class Algo{ public: enum{yuv,nccf,sift} algoID; Algo(); static Algo * init(int algoID); // wobei init ziemlich unpassender name ist, eher was mit create bitte virtual bool identify (int data)=0; virtual ~Algo(); };deine cpp koennte dann so aussehen ....
Algo* Algo::init(algoId) { Algo* tret = NULL; switch(algoID) { case 0: tret = new YUV(); break; case 1: tret = new NCCF(); break; case 2: tret = new SIFT(); break; } return tret; } ; // und was noch so fuer algo brauchst ... Ctor Dtor Algo::Algo { // .. } Algo::~Algo { // .. }Aufruf gaenge dann so:
Algo::algoID aId = Algo::yuv; // oder was auch immer // Algo* algo = Algo::init (aId); // statische methode aufrufen ! algo->identify(img);Ciao ...
-
ok, ich habe das genauso umgesetzt, allerdings meckert der Compiler:
Cpp:
Algo* Algo::create(algoId) { Algo* al = NULL; switch(algoID) { case 0: al = new YUV(); break; case 1: al = new NCCF(); break; case 2: al = new SIFT(); break; } return al; } ;h.:
int algoId = 1; class Algo{ public: enum{yuv,nccf,sift} algoId; Algo(); static Algo * create(int algoId); virtual bool identify (int data)=0; virtual ~Algo(); };Der Compiler sagt:
1. im Cpp: error C2597: illegal reference to non-static member 'Algo::algoId'
2. error C2761: 'Algo *Algo::create(int)' : member function redeclaration not allowedHmmmmmmmmmmmmmmmm ?
-
Du verwendest den Namen "algoID in drei verschiedenen Zusammenhängen (globale Variable, enum-Typ, Methoden-Parameter), das kann nicht gutgehen:
class Algo { public: enum{yuv,nccf,sift} algoID; Algo* create(algoID id) ... }; Algo* Algo::create(Algo::algoID id) { switch(id) { case yuv: return new YUV(); case nccf: return new NCCF(); case sift: return new SIFT(); default: return NULL; } }
-
CStoll (off) schrieb:
Du verwendest den Namen "algoID in drei verschiedenen Zusammenhängen (globale Variable, enum-Typ, Methoden-Parameter), das kann nicht gutgehen:
class Algo { public: enum{yuv,nccf,sift} algoID; Algo* create(algoID id) ... }; Algo* Algo::create(Algo::algoID id) { switch(id) { case yuv: return new YUV(); case nccf: return new NCCF(); case sift: return new SIFT(); default: return NULL; } }Jetzt hier unten bei dem case:
benutze ich dann "case yuv:"oder "case 0:" ? Eigentlich definiere ich doch in meinem Enum, dass 0 yuv ist und 1 nccf usw.Verstehe ich das etwa falsch?
-
Und es kommen immernoch Fehler beim Compilieren:
static Algo * create(int algoID id);error C2146: syntax error : missing ',' before identifier 'id'
Algo* Algo::create(Algo::algoID id) {error C2039: 'algoID' : is not a member of 'Algo'
error C2065: 'algoID' : undeclared identifier
error C2146: syntax error : missing ')' before identifier 'id'
error C2761: 'Algo *Algo::create(int)' : member function redeclaration not allowed
Irgendwie komisch!