Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » warum nicht immer virtual?

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 < [ 2 ]
000
11.10.2007, 00:13 Uhr
Lensflare



Hallo

mich beschäftigt eine Frage.

Also man muss ja vor einer Methode das Keyword "virtual" schreiben, wenn die überschriebene Methode verwendet werden soll. Sonst wird die Methode der Basisklasse verwendet.

Wieso wird nicht einfach immer die überschriebene Methode verwendet?

Es macht doch keinen Sinn, eine nicht virtuelle Methode zu überschreiben, wenn diese sowieso nicht verwendet wird, sondern die der Basisklasse.

Diese Frage hat sich mir gestellt, als ich gemerkt hatte, dass ich ja eigentlich grundsätzlich alle Methoden virtuell machen kann und auch sollte.
Ich entwickle nämlich eine kleine Klassenbibliothek wo der Benutzer eigene Klassen von einer bestimmten Klasse meiner Bibliothek ableitet und es soll ihm ja schließlich möglich sein alle Methoden der Basisklasse zu überschreiben. Und das geht nur wenn alle virtual sind.
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
11.10.2007, 08:56 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja wenn du in der basisklasse die funktion als "virtual" definierst, ist sie in allen abgeleiteten klassen virtual, selbst wenn man es da nicht explizit angibt.

Ansonsten ist da natürlich auch das Problem, das man sonst u.U die Teile der Basisklasse nicht mehr so direkt in der eigenen Funktion verwenden kann.

Teilweise ist das ja sogar gewollt, das je nach Kontext eine andere Funktion aufgerufen wird. Daher ist das so.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
11.10.2007, 08:58 Uhr
mike
Pinguinhüpfer
(Operator)


http://de.wikipedia.org/wiki/Tabelle_virtueller_Methoden
Durch das Lookup vergeht mehr Zeit - aber ein guter Compiler greift da schon dementsprechend ein.
--
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
11.10.2007, 09:18 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


Äh das stimmt doch überhaupt nicht

Wenn du Klasse B von Klasse A ableitest und dabei eine nicht virtuelle Methode von A überschreibst und diese dann mit einer Instanz von B aufrufst dann wird immer die Methode aus Klasse B aufgerufen.
Folgendes Beispiel gibt ABA aus:

C++:
#include <iostream>

using namespace std;

class A
{
public:
    A(){}

    void print()
    {
        cout<<"A";
    }
};

class B : public A
{
public:
    B(){}

    void print ()
    {
        cout<<"B";
        A::print();
    }
};

int main()
{
    A a;
    B b;
    a.print();
    b.print();
    return 0;
}



Der Sinn von virtual ist wenn du für einen Zeiger auf die Basusklasse eine Instanz der abgeleiteten Klasse erstellst die Methode aus der abgeleiteten Klasse aufgerufen wird.
Das heißt

C++:
A *a;
a = new B();
a->print();


gibt A aus wenn print nicht virtuell ist und BA wenn man es virtuell markiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
11.10.2007, 09:47 Uhr
FloSoft
Medialer Over-Flow
(Administrator)



Zitat:

Der Sinn von virtual ist wenn du für einen Zeiger auf die Basusklasse eine Instanz der abgeleiteten Klasse erstellst die Methode aus der abgeleiteten Klasse aufgerufen wird.



Davon bin ich ausgegangen, wenn er eine Bibliothek zum "Überladen" bereitstellt, wird er auch Allokatoren haben für seine Typen, die ebenfalls überladbar/setzbar sind dann innerhalb der Bibliothek die überladenen Typen erzeugen, sonst macht das ganze ja keinen Sinn.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
11.10.2007, 10:52 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


hmm weiß nicht aufgrund dieser Aussage

Zitat von Lensflare:

Also man muss ja vor einer Methode das Keyword "virtual" schreiben, wenn die überschriebene Methode verwendet werden soll. Sonst wird die Methode der Basisklasse verwendet.
Wieso wird nicht einfach immer die überschriebene Methode verwendet?


hab ich das anders verstanden, aber mal schauen
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
11.10.2007, 12:23 Uhr
Lensflare



achso, es macht also einen Unterschied, ob man die Methode über ein Objekt oder über einen Zeiger aufruft. wusste ich nicht.

Aber warum macht es einen Unterschied? Wieso wird bei C++ nicht auch bei Methoden von Zeigern die überschriebene Methode aufgerufen? Wieso muss da plötzich ein virtual hin?
Hat das einen praktischen Sinn oder hat das eher irgendwas damit zu tun, dass es Aufgrund der Polymorphie nicht anders geht?


Zitat von FloSoft:

Davon bin ich ausgegangen, wenn er eine Bibliothek zum "Überladen" bereitstellt, wird er auch Allokatoren haben für seine Typen, die ebenfalls überladbar/setzbar sind dann innerhalb der Bibliothek die überladenen Typen erzeugen, sonst macht das ganze ja keinen Sinn.


Tut mir Leid. Ich verstehe nicht, was du damit meinst. Ich habe zwar nach Allokatoren gegoogelt aber bin daraus nicht schlau geworden.
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
11.10.2007, 12:39 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


Das kommt auf die Zeigerdeklaration drauf an.
Schau dir nochmal mein Beispiel oben an. Der Zeiger wird als A* deklariert und dann aber eine Instanz von B zugewiesen.

Wenn es jetzt A* a = new A(); wäre dann würde immer die Methode von A aufgerufen werden, bei B* a = new B(); immer die von B.

virtual brauchst du nur wenn sich das "vermischt".
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
11.10.2007, 13:58 Uhr
FloSoft
Medialer Over-Flow
(Administrator)



Zitat von Guybrush Threepwood:


virtual brauchst du nur wenn sich das "vermischt".

genau, wenn du also über ein Basisobjekt die (überschriebene) Funktion der Unterklasse aufrufen möchtest, also sowas:


C++:
class A { virtual func() { print "A" } };
class B : public A { func() { print "B" } };

A *a = new B;
a->func();



ohne virtual würde er da dann ein "A" in dem pseudocode ausgeben, mit eben das "B"

Allokatoren bzw "Factorys" musste halt benutzen wenn du innerhalb deiner Bibliothek funktionen hast, die Objekte (die evtl überladen worden sein können) erzeugt werden. Da sonst der Endanwender keine überladenen Objekte bekommt, sondern nur die Basisobjekte, was dann zu zig Speicherfehlern o.ä führen kann.
--
class God : public ChuckNorris { };

Dieser Post wurde am 11.10.2007 um 13:59 Uhr von FloSoft editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
11.10.2007, 18:59 Uhr
Lensflare



ok ich glaube jetzt verstehe ich es.
wenn eine Methode virtuell ist, wird sie anhand des Objekts ausgewählt.


C++:
class A { virtual func() { print "A" } };
class B : public A { func() { print "B" } };

A *a = new B;
a->func(); //a ist ein Objekt von B, also print B



Und wenn die Methode nicht virtuell ist dann wird nur auf die Klasse geschaut, in der das Objekt "steckt", egal ob das Objekt auch tatsächlich von dieser klasse ist oder nicht.


C++:
class A { func() { print "A" } };
class B : public A { func() { print "B" } };

A *a = new B;
a->func(); //a ist ein irgend ein Objekt in Klasse A, also print A



ich hoffe das stimmt so
Damit gäbe es auch einen Grund, Methoden nicht virtuell zu machen.
Nach diesem Grund habe ich gesucht.
--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ 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: