Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Allgemeine Fragen zu virtuellen Funktionen

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
06.06.2004, 16:31 Uhr
Vriza



Hallo!

Ich habe ein paar allgemeine Fragen zu virtuellen Funktionen:

1. Wann und warum verwendet man virtuelle Funktionen?

2. Was bewirkt das Schlüsselwort virtual vor einer Funktion?

3. Wie funktioniert der Mechanismus einer virtuellen Funktion?

Danke schonmal

mfG
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
06.06.2004, 16:39 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


virtual heisst nix weiter das du die mehtode wenn ne andere klasse sie geerbt hat überschreiben darfst... wenn du nicht vor hast zu vererben brauchst du virtual auch nicht
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 06.06.2004 um 16:39 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
06.06.2004, 16:43 Uhr
DerSchwarzeSchlumpf




Zitat:
Vriza postete
Hallo!

Ich habe ein paar allgemeine Fragen zu virtuellen Funktionen:

1. Wann und warum verwendet man virtuelle Funktionen?

2. Was bewirkt das Schlüsselwort virtual vor einer Funktion?

3. Wie funktioniert der Mechanismus einer virtuellen Funktion?

Danke schonmal

mfG


hi

bin zwar auch noch c++-anfänger aber soweit ich das verstanden habe:

grundsätzlich stehtn "virtual functions" im zusammenhang mit "klassen". hier geht es um die möglichkeiten der "vererbung" (polymorphismus). dh du hast eine basisklasse a und von dieser leitest du die klasse b ab.
beispiel:

C++:
class A
{
   public:
     unsigned getNumber() {return number_;}
     void setNumber(unsigned number) {number_ = number;}

   private:
      unsigned number_;
}

class B : public A
{
    public:
      bool numberIsSet() {return number_set_;}

    private:
      bool number_set_;
}



Klasse B verfügt hier also über ALLE (dank public ableitung) elemente der Klasse A und hat zusätzlich noch die weiter definierten.

hier ist der einatz von virtal noch nicht möglich, aber wenn du eine funktion in der Basisklasse A hast, von der du aber willst, dass sie in der Klasse B etwas anderes macht, so brauchst du das "virtual".

dh

C++:
class A
{
   public:
     unsigned getNumber() {return number_;}
     void setNumber(unsigned number) {number_ = number;}
     virtual void doSomethingSpecial();

   private:
      unsigned number_;
}

class B : public A
{
    public:
      bool numberIsSet() {return number_set_;}
      void doSomethingSpecial()

    private:
      bool number_set_;
}



so kannst du die Funktion doSomethingSpecial einmal für die Basisklasse A und dann extra einmal für die Klasse B deklarieren so dass sie dann beide eigenständig etwas verschiedenes machen.
soweit ich das bis jetzt mitbekommen hab ist das vor allem für diverse "display"-funktionen sicher eine klasse sache *g*

aber die "expertn" hier können dir da sicher mehr weiterhelfen (:
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
07.06.2004, 09:52 Uhr
KaraHead



hmm virtual, ist das nicht ein user aus dem Fun-Soft Forum?
Ob und wieviele funktionen er hat weiss ich nicht

-gruß Karahead
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
08.06.2004, 08:41 Uhr
stephanw
localhorst


Der Grund ist (wie der Schlumpf schon richtig beschrieben hat) der sog. Polymorphismus. Damit bezeichnet man das Verhalten eines Objekts, vielgestaltig zu sein. Dies macht nur mit Vererbung Sinn. Wenn man "public" erbt, erbt man die oeffentliche Schnittstelle der Basisklasse mit. Insbesondere ist jedes Objekt der Unterklasse ueberall dort einsetzbar, wo auch ein Objekt der Oberklasse (==Superklasse) einsetzbar ist. Dennoch haben die beiden Objekte verschiedenes Verhalten, da die virtuellen Funktionen in der Unterklasse ja ueberschrieben worden (sein koennen). Dies ist aber fuer den Aufrufer transparent. Bsp:


C++:
class A {
public:
    virtual void move (int feet) {
        // code
    }
};

class B : public A {
public:
    virtual void move (int feet) {
        // andere Code
    }
};

void f (A* p) {
    p->move (10);
}

int main () {
    A* a = new A ();
    B* b = new B ();
    f (a);
    f (b);
    return 0;
}


Der Aufruf f(b) geht, weil jedes B auch ein A ist. Weil move () virtual ist, wird automatisch die richtige Funktion aufgerufen, obwohl es fuer f voellig transparent ist, ob p nun vom Typ A oder B ist.
Um diese Art Polymorphismus zu erreichen, MUSS der Funktionsaufruf ueber .Zeiger oder Referenz gemacht werden. Virtuelle Funktionen muessen in der Ableitung 100 % die gleiche Signatur haben, damit sie "ueberschrieben" werden.

Das funktioniert wohl i.d.R. durch eine virtuelle-Funktionen-Ttabelle. Dort steht (fuer jede Klasse) die Adresse der richtigen Funktion drin. Jedes Objekt hat dann einen Zeiger auf die Tabelle seiner Klasse, der eben 4 Byte mehr beansprucht. Dies ist fuer den Programmierer transparent, laesst sich aber mit sizof testen .Der Funktionsaufruf ist wegen der Tabelle indirekt.

Sonst gibt es "rein virtuelle" Funktionen noch mit dem Suffix "= 0"

C++:
class Foo {
public:
    virtual void doSomething () = 0;
};


die in der Ableitung ueberschrieben werden MUESSEN. Foo ist damit abstrakt (es koennen keine Objekte angelegt werden).

Bis neulich!
--
Reden ist Schweigen und Silber ist Gold.

Dieser Post wurde am 08.06.2004 um 08:43 Uhr von stephanw editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
08.06.2004, 09:38 Uhr
ao

(Operator)


Anwendungsbeispiel:


C++:
class CSaeugetier
{
    public:
        virtual void Walk ()
        {
                // Code zum Laufen auf 4 Beinen, wie die meisten Saeugetiere
        }
};

class CHund : public CSaeugetier
{
    // erbt Walk-Methode (fuer 4 Beine) von CSaeugetier
};

class CMensch : public CSaeugetier
{
    public:
        virtual void Walk ()
        {
            // Dieses Saeugetier laeuft auf 2 Beinen, muss also die Walk-Methode ueberschreiben.
        }
};

int main (void)
{
    CSaeugetier * pTier [2]; // 2 Saeugetiere
    pTier[0] = new CHund;
    pTier[1] = new CMensch;

    // alle laufen
    pTier[0]->Walk (); // auf 4 Beinen
    pTier[1]->Walk (); // auf 2 Beinen

    // delete nicht vergessen, lass ich hier mal weg.

    return 0;
}


Dieser Post wurde am 08.06.2004 um 09:38 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
08.06.2004, 09:43 Uhr
stephanw
localhorst


Echt geil ich habe bei meinem Bsp. kurz ueberlegt, eines mit Tier, Hund und Mensch zu machen...
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
30.01.2006, 10:34 Uhr
huckleberry



dann kann man sagen
(c++) VIRTUAL == (java)ABSTRACT ?

oder gibts da irgendwelche unterschiede?
--
There are 10 types, those who understand binary and those who don't...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
30.01.2006, 11:11 Uhr
virtual
Sexiest Bit alive
(Operator)


@huckleberry

Ja, da gibt es unterschiede: das eine sind Äpfel, das andere Birnen.

Eine Abstrakte methode (welche es auch in C++ gibt) ist eine Methode, welche keine Implementierung hat. Klassen mit abstrakten methoden können nicht instantiiert werden. Im Allgemeinen verwendet man abstrakte Methoden für Basisklassen, bei denen zwar klar ist, daß sie in der Ableitung existieren müssen, aber es keine sinnvolle Implementierung in der Basisklasse gibt.

In Java sind generell alle Methoden virtuell (bis auf die Statischen methoden), in C++ gibt es virtuelle und nicht virtuelle Methoden. Mit ein wenig Nachdenken kommt man schnell dahinter, daß eine Abstrakte Method zwar stets virtuell sein muß, jedoch gilt die Umkehrung nicht.
--
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
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: