Forum: PC-Programmierung C++ Methoden Durchlauf


von Maraike (Gast)


Lesenswert?

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

von Εrnst B. (ernst)


Lesenswert?

Bring erstmal das Programm soweit in Ordnung, dass der Compiler es 
akzeptiert, und du wenigstens eine Methode erfolgreich aufrufen 
kannst, undabhängig von Parametern...

von Sharping (Gast)


Lesenswert?

Maraike schrieb:
> Auf jeden Fall möchte ich keine Switch Case Abfrage verwenden.

Weil??? Wäre doch in deinem Fall genau das Richtige...

von Maraike (Gast)


Lesenswert?

Ü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

von Εrnst B. (ernst)


Lesenswert?

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...

von Maraike (Gast)


Lesenswert?

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.

von kopfkratzer (Gast)


Lesenswert?

kopfkratz
Und wo ist da nun was objekorientiertes ?
Ein Lösungsansatz ist ja schon genannt worden, vielleicht mal im 
Stroustrup nachlesen ?

von Maraike (Gast)


Lesenswert?

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?

von Vlad T. (vlad_tepesch)


Lesenswert?

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.

von Vlad T. (vlad_tepesch)


Lesenswert?

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(&gtB);
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

von Maraike (Gast)


Lesenswert?

Danke das hilft mir weiter. Kann geschlossen werden.

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
Noch kein Account? Hier anmelden.