Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

20.08.2012, 15:45

Rausfinden von welcher Klasse geerbt wurde...? [C++]

Hallo,

mein Problem, ich möchte herausfinden von welcher Klasse, die Klasse A, ... erbt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class A: public B
{
    // ...
};

class B
{
    // ...
};

class C : public D
{

};

class D
{

};

// "Allgemeine" Listen:
std::list<B> bListe;
std::list<D> dListe;

// Wozu ich es brauche:
template <class T>
void add(std::list<T> &list)
{
   for( /* Alle Objekte der übergebenden Liste durchgehen */ )
   {
      if     ( /* Objekt erbt von Klasse B */ ) /* Füge der "allgemeinen" Liste B das Objekt hinzu */ bListe.push_back(aObj);
      else if( /* Objekt erbt von Klasse D */ ) /* Füge der "allgemeinen" Liste D das Objekt hinzu */ dListe.push_back(cObj);
   }
}


Leider musste ich feststellen das man mit typeid(...) nur die Basis Klasse raus bekommt.
Deswegen die Frage, wie finde ich heraus von welcher Klasse A erbt um das jeweilige Objekt
dann in die richtige Liste hinzuzufügen?

Ich hoffe man versteht was ich möchte.
Vielen Dank im Voraus! :)

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

2

20.08.2012, 15:48

Stichwort RTTI.
Sieht aber schwer nach einem Designfehler aus. In der Regel kommt man ohne RTTI aus.
Wieso gibst du den Klassen nicht eine virtuelle Methode, die das Objekt in die Liste einfügt?
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

3

20.08.2012, 15:50

Das geht mit dynamic_cast. Allerdings ist es meistens eine schlechte Idee das überhaupt zu benutzen (widerspricht der Idee von dynamic binding). Warum glaubst du, dass du eine solche Fallunterscheidung brauchst? Sehr wahrscheinlich gibt es eine bessere, bereits allgemein etablierte Method das zu tun. ;)

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

4

20.08.2012, 17:18

Ich schließe mich an, das sieht so aus, als willst du sehr wahrscheinlich keine Listen B und D, sondern eine gemeinsame Liste. Unterschiedliche Verhalten werden dann über virtuelle Methoden gelöst.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

5

20.08.2012, 19:01

Wieso wusste ich schon bevor ich diesen Thread erstellt habe dass ich dieses Problem mit virtuellen Methoden,
dem Thema mit dem ich mich noch nicht beschäftigt habe, lösen kann...? ^^

Werde mich wohl dann erst mal einlesen und wieder was neues dazu lernen (*freu*), wenn ich
Schwierigkeiten habe melde ich mich in diesem Thread nochmal!

Danke für eure schnellen Antworten! :)

RmbRT

Treue Seele

Beiträge: 169

Wohnort: Darmstadt

Beruf: Student

  • Private Nachricht senden

6

21.08.2012, 14:09

weis nicht obs hilft, aber ich würde es mit der methode

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
struct no_type { long unused; };
struct yes_type { char unused; };

//prüfe, ob T von Base abstammen kann
template<class T, class Base>
struct hasBaseClass
{
  static yes_type test(Base *);
  static no_type test(...);
  enum {value = sizeof(test(dynamic_cast<T*>(0))) == sizeof(yes_type) };
};

machen (ich hoffe, es ist kein Fehler drin :rolleyes: ).
und dann so verwenden:

C-/C++-Quelltext

1
2
if(hasBaseClass<T, B>::value) addToBList(elem);
else addToDList(elem);

oder ganz einfach:

C-/C++-Quelltext

1
2
3
4
5
void addToList(B* elem){ blist.add(elem); }
void addToList(D* elem){ dlist.add(elem); }

//und dann einfach
addToList(elem);


MfG, RmbRT
"Dumm ist, wer dummes tut."

7

22.08.2012, 18:11

Neues Problem. Ich hoffe das darf noch in diesen Thread.

Und zwar:

Ich möchte ein Objekt A in eine Liste "Liste für Objekte A" einfügen, allerdings gibt es auch noch Objekt B, C, ... usw. die ich in die
richtige Liste hinzufügen möchte. Der Quelltext dazu:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
std::list<A> objectAList;
std::list<B> objectBList;
std::list<C> objectCList;
// ...

template <class T>
void add(T &templateObject)
{
   if(typeid(templateObject) == typeid(A)) objectAList.push_back(templateObject);
   if(typeid(templateObject) == typeid(B)) objectBList.push_back(templateObject);
   if(typeid(templateObject) == typeid(C)) objectCList.push_back(templateObject);
   // ...
}

Wahrscheinlich kann sich der ein oder andere schon denken was für ein Problem ich habe... "falscher Datentyp angegeben"...

.. Leider, wird nun mal schon beim Kompilieren überprüft ob das eingesetzte Objekt in die Liste rein darf oder nicht... und leider ignoriert der Compiler
natürlich die abfragen (logisch) und möchte mich am liebsten steinigen, weil ich nun mal angeblich unbedingt Objekte mit einem Datentyp in
Listen einfügen möchte, die nicht für diesen Datentyp ausgelegt sind...

Er reagiert halt nach dem Motto, als wenn ich z.B zwei String Objekte einer Funktion mit der Parameter Liste (float, float) übergeben möchte.

So und jetzt stehe ich nun mal (so wie oft) gerade auf einem Schlauch, mir fällt echt nichts dazu ein... Scheint wohl auch ne Design schwäche zu sein, richtig?
Ich wäre enorm dankbar, wenn mir dabei jemand helfen könnte. Ein Denkanstoß würde schon genügen. :)

@Rmbrt, ich hab ja nicht umsonst Templates verwendet, ich wollte es umgehen unmengen von überladenen Funktionen zu erstellen... :P
Und ersteren Code verstehe ich nicht so ganz, allerdings ist das auch nicht mehr das größte Problem, da ich diesen Teil schon hin bekommen habe... Danke trotzdem dafür. :)

8

22.08.2012, 18:19

C-/C++-Quelltext

1
2
3
void add(A &object) {
    objectAList.push_back(object);
}


Usw...

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

9

22.08.2012, 18:22

In wiefern ist das jetzt ein neues Problem?

Zitat

@Rmbrt, ich hab ja nicht umsonst Templates verwendet, ich wollte es umgehen unmengen von überladenen Funktionen zu erstellen...

Das ist nicht der Sinn von templates. Templates sind dazu da Teile von einem Code unabhängig von deren Typen zu machen und nur eine gewisse Schnittstelle zu verlangen.

So wie es jetzt schon mehrmals genannt wurde und Delop auch nochmal zeigt wirds gemacht. Zuerst templates zu benutzen und dann den Typen herausfinden zu wollen macht keinen Sinn.

10

22.08.2012, 18:33

Zitat

Templates sind dazu da Teile von einem Code unabhängig von deren Typen zu machen und nur eine gewisse Schnittstelle zu verlangen.

Das habe ich theoretisch ja auch versucht...?

Zitat

Zuerst templates zu benutzen und dann den Typen herausfinden zu wollen macht keinen Sinn.

Ich finde es irgendwie nicht sinnlos... ich glaube da kann man sich streiten.

...

Also führt kein Weg an überladenen Funktionen vorbei?

Werbeanzeige