Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » virtual und polymorphismus

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
24.07.2004, 16:43 Uhr
DerSchwarzeSchlumpf



hi (:

... ich hab hier einige sachen ausprobiert, aber ich blick hier bei einigen nicht wirklich durch.

also, "grundsätzliche" ableitungen und was virtual grundsätzlich macht sind mir klar.

ABER! *g* ein paar "spezialfälle"? (die viell. gar keine sind sondern ich einfach auf der leitung steh) machen mir doch zu schaffen... .

1) wenn ich virtuell ableite


C++:
class Base
{
  public:
  Base();
  ~Base();
  virtual doSomething();
}

class Ableitung : virtual Base
{
  Ableitung();
  ~Ableitung();
  virtual doSomething();
}



was wird hier durch die virtuele-Ableitung nun alles übernommen? Was wäre, wenn ich in der "Abletung" die Methode doSomething nicht als virtual deklariere bzw. sie komplett weglassen würde? Wenn ich sie weglassen würde, würde ja die Methode von der Base übernommen werden. Wenn ich sie nicht virtual-deklarieren würde, würde er sie mir nur nicht in die interne Virtual-Tabelle aufnehmen und bei einer weiteren Ableitung2 von Ableitung auf die doSomething im Base zurückgreifen, oder?



2) Ich hab mehrere Klassen

C++:
class A
{
virtual doSomething();
}

class B : A
{
doSomething();
}

class C : B
{
virtual doSomething();
}

class D : C, A
{
}



und wenn ich hier jetzt dann im Objekt vom Typ D die Methode doSomething aufrufen, nimmt er mir die Methode von C. Wenn es die in C nicht gäbe, würde er mir die von A nehmen, oder?

entweder steh ich komplett auf der leitung und hab eigentlich keinen Plan was virtual macht, oder ich hab nur einen knoten im kopf *g*

hoffe dass klar ist was ich nicht ganz versteh *g*
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
24.07.2004, 16:58 Uhr
0xdeadbeef
Gott
(Operator)


Polymorphismus ist noch mal was ganz anderes, also lasse ich das mal außen vor.

virtual ist im Grunde ein Keyword, das sagt, dass Funktionen oder Oberklassen als Referenz gehalten werden. Bei Funktionen ist der Sinn folgender:

C++:
struct A { void do_some() { std::cout << "A" << std::endl; } };
struct B : public A { void do_some() { std::cout << "B" << std::endl; } };

void call_do_some(A &a) { a.do_some(); }

//...

B b;
call_do_some(b); // gibt A aus

/////////////////////////////////////////////////////////////
struct C { virtual void do_some() { std::cout << "C" << std::endl; } };
struct D : public C { virtual void do_some() { std::cout << "D" << std::endl; } };

void call_do_some(C &c) { c.do_some(); }

//...

D d;
call_do_some(d); // gibt D aus


Bei virtueller Vererbung erschließt sich das nur aus Mehrfachvererbung:

C++:
struct A { void method() { } }
struct B : public A { };
struct C : public A { };
struct D : public B, C {
  void my_method() {  method(); /* <-- C::method oder B::method? Was geben wir als this mit? */ }
};


Wenn du dagegen schreibst:

C++:
struct A { void method() { } }
struct B : virtual public A { };
struct C : virtual public A { };
struct D : public B, C {
  void my_method() {  method(); /* Deine Basisklassen B und C verweisen auf die selbe Instanz von A, auf diese Art ist es eindeutig. */ }
};


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
24.07.2004, 17:09 Uhr
DerSchwarzeSchlumpf



hi

danke erstmal schon für deine antwort

ok das aus dem 1. beispiel hab ich jetzt verstanden *g* hab dazu was abgetippt und mir den output angeschaut

C++:
#include <iostream>
#include "windows.h"

using namespace std;

using std::cout;
using std::endl;

class Base
{
public:
  void firstMethod()
  {
    cout << "bfm ";
  }
  virtual void secondMethod()
  {
    cout << "bsm " << endl;
  }
};

class Derived : public Base
{
public:
  void firstMethod()
  {
    cout << "dfm ";
  }

  virtual void secondMethod()
  {
    cout << "dsm" << endl;
  }
};

void callPrintMethods(Base & obj)
{
  cout << "cpmp ";
  obj.firstMethod();
  obj.secondMethod();
}

void callPrintMethods(Derived & obj)
{
  cout << "cpmd ";
  obj.firstMethod();
  obj.secondMethod();
}

int main()
{
  Derived my_obj;
  callPrintMethods(static_cast<Base &>(my_obj));
  callPrintMethods(my_obj);
  system("Pause");
  return(0);
}


und der output ist
cpmp bfm dsm
cpmd dfm dsm


beim 2. beispiel blick ich trotzdem irgendwie noch nicht so ganz durch *schäm* *g* heißt das virtual in der ableitung da, dass hier (mal leienhaft ausgedrückt *g*) nicht direkt ein objekt angelegt wird und alles auf das "echte" basis-objekt (in dem fall A) beziehn?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
26.07.2004, 14:56 Uhr
virtual
Sexiest Bit alive
(Operator)


so ähnlich...
Als im beefies Beispiel haben wir ja die Klassen A - D. Offenkundig enthalten die Klassen B und C jeweils auch alles von A, weil sie ja von A abgeleitet worden sind.

Losgelöst von der Syntax könnte man sich für D nun also folgende Alternativen vorstellen:

1. Ein D enthält ein B und ein C. Weil B und C jeweils ein A enthalten, enthält D also auch den A - Anteil von B sowie den A - Anteil von C.

2. Ein D enthält ein B, C und auch ein A. Dh B und C müssen sich das A teilen.

Die letztere Variante hat man, wenn man mit virtual ableitet, erstere ohne virtual.

Es muß nun jeder für sich selbst entscheiden, was er davon hält, ich persönlich finde es nicht grade ein Feature, sondern nur einen verzweifelten Versuch ein Fehldesign zu retten:

Offenkundig ist es nämlich so, daß man sich bereits bei dem Design von B und C gedanken darüber machen muß, ob man diese Klassen jemals in einer Mehrfacherbung haben möchte und wenn ja auf welche Weise. Dies ist nicht immer vorhersehbar, grade wenn es um wiederverwendbaren Code geh, und macht bei komplexeren Programmen ganz gerne mal nachhaltig Probleme. Deshalb findet man häufig in Firmeninternen Codestyleguides die Anweisung bereits in der Designphase Mehrfachvererbung soweit als möglich zu meiden...
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
26.07.2004, 15:41 Uhr
DerSchwarzeSchlumpf



super, danke (: jetzt hab ichs echt verstanden
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
27.07.2004, 11:22 Uhr
~Dirk
Gast


Hi,

wirklich eine super Erklärung. Nun habe ich innerhalb weniger Minuten die virtuelle Vererbung verstanden, was mir vorher immer ein Rätsel war. Ich denke, dass es sinnvoll wäre diesen Beitrag in die FAQ zu stecken.

Was meint ihr dazu?

Gruß

Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: