Hallo zusammen, ich habe folgendes Problem: ich habe 3 Klassen class A { ... public: meth1(); }; class B { ... public: meth2(); }; class C { ... public: meth3(); }; um Variable zu sein möchte ich die 3 Methoden je nach Konfiguration des Konstruktors in unterschiedlicher Reienfolge abarbeiten. int main(void) { ... for( u8TaskCount = 0u; u8TaskCount < u8MaxTasks; u8TaskCount++ ) { // Je nach mitgabewert des Konstruktors meth1(); meth3(); meth2(); // oder meth2(); meth3(); } } In C hätte ich das über eine Tabelle mit Funktionspointern gemacht aber in C++ habe ich noch keine Möglichkeit gefunden dieses Problem sauber zu lösen. Auf jeden Fall möchte ich keine Switch Case Abfrage verwenden. Ich hoffe ihr könnt mir weiterhelfen. Gruß Maraike
Bring erstmal das Programm soweit in Ordnung, dass der Compiler es akzeptiert, und du wenigstens eine Methode erfolgreich aufrufen kannst, undabhängig von Parametern...
Maraike schrieb: > Auf jeden Fall möchte ich keine Switch Case Abfrage verwenden. Weil??? Wäre doch in deinem Fall genau das Richtige...
Über diesen Schritt bin ich schon längst hinaus. Also bitte keine Klugscheißer Kommentare mehr. ACHTUNG - Der obige Code ist nur ein abstraktes Beispiel und kann natürlich nicht so compiliert werden - ACHTUNG
Vermutlich soll die Hausaufgabenstellung folgendes Ergebnis bringen: - Die drei Klassen erben von einer gemeinsamen Basis. - Die Methode heißt immer gleich, und ist in der Basis als Virtuell markiert. - Je nach Aufruf-Parameter wird eine Basisklassenpointer-Liste befüllt. (analog der Funktionspointer-Liste in C) - Durchlaufen der Liste, Aufrufen der Methode auf jedem Element...
Insgesamt sind es 30 Methoden die je nach Plattform anders konfiguriert werden sollen. Ich möchte keine Switch Case da dann bis zu 30 Methoden überprüft werden.
kopfkratz Und wo ist da nun was objekorientiertes ? Ein Lösungsansatz ist ja schon genannt worden, vielleicht mal im Stroustrup nachlesen ?
Hallo B*, bitte gib kein Kommentar ab wenn du die Problematik noch nicht verstanden hast. Es ist keine Schande nachzufragen, vielleicht ist mein Beispiel nicht für jeden verständlich. Wie im obigen Beispiel dargestellt existieren 3 Basisklassen mit ihren Methoden die vollkommen unterschiedlich heißen. Und ich möchte in einer Art Runtime diese Methoden ( die nichts mit einander gemein haben ) in unterschiedlicher Abfolge Abfragen. Eine Klassenliste hilft mir da nicht weiter. Hat vielleicht noch jemand eine Idee?
Ich glaub der TO benötigt ein gutes C++ Tutorial Ich fände folgenden Ansatz sehr viel besser:
1 | class BaseTask |
2 | {
|
3 | public:
|
4 | virtual void processingStep()=0; |
5 | }
|
6 | |
7 | class Task1:public BaseTask |
8 | {
|
9 | public:
|
10 | virtual void processingStep(){ |
11 | //tue was
|
12 | };
|
13 | }
|
14 | |
15 | class Task2:public BaseTask |
16 | {
|
17 | public:
|
18 | virtual void processingStep(){ |
19 | //tue was anderes
|
20 | };
|
21 | }
|
22 | |
23 | class Task3:public BaseTask |
24 | {
|
25 | public:
|
26 | virtual void processingStep(){ |
27 | //tue was ganz anderes
|
28 | };
|
29 | }
|
30 | |
31 | class BaseScheduler |
32 | {
|
33 | public:
|
34 | virtual letATaskStep()=0; |
35 | virtual addTask(BaseTask* i_task) = 0; |
36 | }
|
37 | |
38 | class RoundRobinScheduler : public BaseScheduler |
39 | {
|
40 | public:
|
41 | RoundRobinScheduler() |
42 | : m_curTask(0) |
43 | , m_numTasks(0) |
44 | {}
|
45 | static const int maxTasks = 10; |
46 | |
47 | virtual letATaskStep(){ |
48 | m_tasklist[m_curTask]->processingStep(); |
49 | ++m_curTask; |
50 | if(m_curTask > m_numTasks) |
51 | m_curTask = 0; |
52 | }
|
53 | |
54 | virtual addTask(BaseTask* i_task) |
55 | {
|
56 | if(m_numTasks<maxTasks) |
57 | m_tasklist[m_numTasks++] = i_task; |
58 | }
|
59 | |
60 | private:
|
61 | int m_curTask; |
62 | int m_numTasks; |
63 | BaseTask* m_tasklist[maxTasks]; |
64 | }
|
65 | |
66 | BaseScheduler* g_sched; |
67 | |
68 | int main() |
69 | {
|
70 | RoundRobinScheduler rrsched; |
71 | Task1 task1; |
72 | Task2 task2; |
73 | Task3 task3; |
74 | g_sched = &rrsched; |
75 | |
76 | sched->addTask(&task1); |
77 | sched->addTask(&task2); |
78 | sched->addTask(&task3); |
79 | |
80 | for(;;) |
81 | {
|
82 | sched->letATaskStep(); |
83 | }
|
84 | |
85 | }
|
PS: ich hab jetzt hier bewusst auf stl container verzichtet, um ohne dynamische Speicherverwaltung auszukommen. Den Code könnte man somit auch auf einen kleinen µC einsetzen. Der Overhead durch die virtuellen Methoden wäre noch imho verschmerzbar.
wenn die Klassen nix miteinander zu tun haben, außer eine identische Memberfunctions-Signatur, dann musst du dies nochmal verpacken. du könntest zB, um bei meinem Beispiel zu bleiben eine template klasse schreiben, die von BaseTask ableitet und als konstruktorargument den Funktionspointer entgegennimmt. Bin mir hier aber mit der Syntax nicht so richtig sicher
1 | template <class T> |
2 | class GenericTask: public BaseTask |
3 | {
|
4 | typedef void (T* obj, T::*MemberFunctionPointer) ();; |
5 | GenericTask( MemberFunctionPointer ptr ) |
6 | : m_ptr(ptr) |
7 | , m_obj(obj) |
8 | {}
|
9 | |
10 | virtual void processingStep(){ |
11 | m_obj->(*m_ptr)(); |
12 | };
|
13 | |
14 | private:
|
15 | T* m_obj; |
16 | MemberFunctionPointer m_ptr; |
17 | };
|
18 | |
19 | |
20 | |
21 | |
22 | ...
|
23 | |
24 | int main() |
25 | {
|
26 | |
27 | ...
|
28 | A a; // deine komische klasse |
29 | GenericTask<A> gtA(&a, &(a->meth1) ); |
30 | B b; // deine komische klasse |
31 | GenericTask<B> gtB(&b, &(b->meth2) ); |
32 | ...
|
33 | sched->addTask(>B); |
34 | }
|
edit: Ergänzung im Code zur Benutzung. Aber ich wette, dass der eigentliche Fehler in deinem Design der Klassen A, B, C liegt. Das ganze ist schon etwas krude
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.