Autor Beitrag
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Mo 09.06.08 17:25 
Hi,

ich hab ne frage zu C++ und der möglichkeit der Mehrfachvererbung.. evtl kann mir ja jemand hier helfen :)
(Es geht um C++ nicht C#.. ich benutze nur die C# code-tags ;) )


Also,
ich habe 3 Klassen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
class Main {
public:
  void helloWorld();
};


class A {
public:
  void doSomething(int x);
};

class B {
public:
  void doNothing(string s);
};


und jetzt eine dritte klasse die IMMER von Main ableitet, und zusätzlich manchmal von A und/oder B:

ausblenden C#-Quelltext
1:
2:
3:
4:
class AB : public Main, public A, public B {
public:
  .....
};


soweit kein problem, aber..
Im code werden die klassen alle als array von Main* gespeichert, aber wenn ich jetzt gern auf die doNothing() funktion zugreifen möchte, wie mach ich das?

Ich ging davon aus, dass ich einfach:

ausblenden C#-Quelltext
1:
((B*)myClass)->doNothing(..);					


verwenden kann, aber das klappt leider nicht, also es kommt dann wohl irgendwie intern durcheinander und ruft falschen code auf...

wenn ich stattdessen schreibe:

ausblenden C#-Quelltext
1:
((AB*)myClass)->doNothing(..);					


geht es, aber die lösung ist für mich eher unpraktisch, da ich halt wie gesagt manchmal auc hnur von A oder B ableite und dementsprechend nicht immer in AB* casten kann...

Die einzige lösung die mir einfiele wären viele if abfragen die überprüfen um welchen typ es sich handelt und dann dementsprechend casten...

Gibt's da irgendwas anderes, besseres?

Aya~

PS: In dem moment wo ich die doNothing() funktion aufrufe weiß ich sicher das das objekt von B geerbt hat, aber ich weiß nicht sicher ob es auch von A geerbt hat = ich kann nicht sicher sagen ob ich nach AB* oder nach BOnly* casten muß..

_________________
Aya
I aim for my endless dreams and I know they will come true!
tommie-lie
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 4373

Ubuntu 7.10 "Gutsy Gibbon"

BeitragVerfasst: Di 10.06.08 11:56 
Folgender Code funktioniert bei mir (g++ (GCC) 4.2.3 (Ubuntu 4.2.3-2ubuntu7)):
ausblenden 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:
#include <iostream>

class Main {
public:
  void helloWorld() { std::cout << "Main::helloWorld" << std::endl; };
};

class A {
public:
  void doSomething(int x) { std::cout << "A::doSomething" << std::endl; };
};

class B {
public:
  void doNothing(float s) { std::cout << "B::doNothing" << std::endl; };
};

class AB : public Main, public A, public B {
};


int main() {

  Main *ab = new AB();
  ab->helloWorld();
  ((A*)(ab))->doSomething(23);
  ((B*)(ab))->doNothing(42);

  return 0;
}
und liefert folgende Ausgabe:
ausblenden Quelltext
1:
2:
3:
4:
thomas@Majestix:/tmp$ ./a.out 
Main::helloWorld
A::doSomething
B::doNothing

Mehr Typsicherheit erhältst du allerdings durch eine polymorphe Vaterklasse und dynamic_casts:
ausblenden volle Höhe 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:
#include <iostream>

class Main {
public:
  void helloWorld() { std::cout << "Main::helloWorld" << std::endl; };
  virtual ~Main() {}; // oder beliebige andere virtuelle Methode
};

class A {
public:
  void doSomething(int x) { std::cout << "A::doSomething" << std::endl; };
};

class B {
public:
  void doNothing(float s) { std::cout << "B::doNothing" << std::endl; };
};

class AB : public Main, public A, public B {
};


int main() {

  Main *ab = new AB();
  ab->helloWorld();
  dynamic_cast<A*>(ab)->doSomething(23);
  dynamic_cast<B*>(ab)->doNothing(42);

  return 0;
}
Getestet und für gut befunden auf dem gleichen System, durch den dynamic_cast sollte auch sichergestellt werden, daß die Methoden tatsächlich existieren, bevor du sie aufrufst.

Wenn A und B selbst wiederum von einer anderen Klasse erben, möglicherweise von einer gemeinsamen Oberlkasse von Main, interessiert dich vielleicht parashift.com/c++-fa...itance.html#faq-25.8 und parashift.com/c++-fa...itance.html#faq-25.9.

_________________
Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Di 10.06.08 12:14 
Yay mit dynamic_cast klappt es, tausend dank!! :)

_________________
Aya
I aim for my endless dreams and I know they will come true!