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

Jo

Frischling

  • »Jo« ist der Autor dieses Themas
  • Private Nachricht senden

1

19.04.2005, 18:22

Reinvirtuelle Klassen

Nur eine kleine Frage: Muss man bei reinvirtuelle Klassen einen Konstruktor und Destruktor haben, oder kann ich diesen einfach löschen, da ja keine Instance von dieser Klasse erstellt werden kann.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

19.04.2005, 18:47

der compiler fügt ja sowieso einen leeren konstruktor und destruktor hinzu...

außerdem empfielt es sich bei rein virtuellen klassen einen virtuellen destruktor zu verwenden, damit immer sichergestellt ist, dass auch der richtige destruktor aufgerufen wird...

Jo

Frischling

  • »Jo« ist der Autor dieses Themas
  • Private Nachricht senden

3

19.04.2005, 22:04

Hab ich da was falsch verstanden oder muss man den Desturktor nur wenn virtuelle Funktionen in der Klasse verhanden sind auch als virtuell deklarieren. Ich dachte, dass man dies mei reinvirtuellen Klassen nicht machen muss, da ja gar keine Instance davon gebildet werden kann.

Mathias

Frischling

Beiträge: 29

Wohnort: Berlin

Beruf: Schüler

  • Private Nachricht senden

4

19.04.2005, 22:20

Egal ob nur virtuelle Methoden in der Klasse sind oder ob die ganze Klasse abstrakt ist,
du solltest in diesen Fällen immer einen virtuellen Destruktor definieren.
Dies hat zur Folge das bei den abgeleiteten Klassen in jedem Fall der neue (überschreibene) Destruktor der abgeleiteten Klasse benutzt wird und das Objekt passend zerstört wird.

weigo

Treue Seele

Beiträge: 234

Wohnort: Deutschland

  • Private Nachricht senden

5

20.04.2005, 08:25

Wenn du nur eine virtuelle Methode definiert hast, dann solltest du auch den Destruktor virtuell machen, aber das wurde ja bereits erwähnt.

Ich bin mir nur nicht sicher bei der Aussage, dass man immer einen virtuellen Destruktor verwenden sollte. Eine virtuelle Methode hat zur Folge, dass eine vtable erzeugt wird. Alle Zugriffe laufen dann über die vtable und man bekommt dadurch einen Performance Hit. Die Frage ist also, ob es sich lohnt eine virtuelle Methode einzusetzen, wenn diese überhaupt nicht nötig ist!
Da bei reiner Vererbung kein virtueller Destruktor zwingend notwendig ist.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

20.04.2005, 15:33

wenn keine virtuellen methoden verwendet werden, dann ist ein virtueller destruktor natürlich auch nicht unbedingt notwendig...

Jo

Frischling

  • »Jo« ist der Autor dieses Themas
  • Private Nachricht senden

7

20.04.2005, 15:42

Ich mach mal ein Beispiel. (vielleicht hab ich mich unklar ausgedrückt)

C-/C++-Quelltext

1
2
3
4
5
6
7
class MeineKlasse
{
    MeineKlasse();
    ~MeineKlasse();
    virtual void IrgendeineFunk()=0;
    virtual void NocheineFunk()=0;
}


Eine reinvirtuelle Klasse benötigt ja keinen Speicher und wiso brauch ich denn da überhaupt noch einen Konstruktor oder Destruktor. Mir ist schon klar, dass wenn in einer Klassen virtuelle Funtionen habe, auch einen virtuellen Destruktor haben sollte. Da aber bei einer reinvirtuellen Klasse keine Implementation aufgerufen werden kann, da ja auch keine Instance gebildet werden kann.

weigo

Treue Seele

Beiträge: 234

Wohnort: Deutschland

  • Private Nachricht senden

8

20.04.2005, 16:03

Es wird eine Instanz erzeugt und zwar im Konstruktor der abgeleiteten Klasse. Diese ruft zu aller erst den Konstruktor der Basisklasse auf. Wenn du dies nicht explizit machst, dann macht es der Compiler für dich.
Beim Destruktor siehts genauso aus.

Quellcode

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
35
36
37
38
39
40
41
42
43
44
class Base1
{
public:
    Base1()
    {
        int x = 0;
    }

    virtual ~Base1() 
    {
        int x = 0;
    }

    virtual void GetSomething() = 0;
};

class Derived : public Base1
{
public:
    Derived(int a, int b)
    {
        int x = 0;
    }

    virtual ~Derived()
    {
        int x = 0;
    }

    void GetSomething() 
    {
        int x = 0;
    }
};

int main()
{
    Derived* d = new Derived(3,4);
    d->GetSomething();

    delete d;

    return 0;
}


Dieses Beispiel macht überhaupt keinen Sinn, aber wenn du es debuggst, wirst du sehen was passiert.

9

20.04.2005, 17:22

Zitat

Eine virtuelle Methode hat zur Folge, dass eine vtable erzeugt wird. Alle Zugriffe laufen dann über die vtable und man bekommt dadurch einen Performance Hit. Die Frage ist also, ob es sich lohnt eine virtuelle Methode einzusetzen, wenn diese überhaupt nicht nötig ist!

Wie immer kommt es darauf an was du mit der Klasse vorhast. Wenn du nie vorhast diese Klasse irgendwann einmal als Basis einer anderen zu benutzen, dann ist ein virtueller Destruktor genauso sinnlos wie virtuelle Funktionen.

Sobald man allerdings eine Klasse als "Interface" benutzen will, egal ob nun nur nicht virtuelle, virtuelle oder rein virtuelle oder das ganze gemischt, wird dir nichts anderes übrigbleiben. Weil ja, wie schon erwähnt wurde, nicht der richtige Destruktor aufgerufen wird.

Was die Performance angeht. V-Table hört sich nach mächtig viel Arbeit an. Ist es aber nicht. Der Aufruf einer nicht virtuellen Methode in einer DLL kostet schon fast mehr Zeit als der aufruf einer virtuelle Methode. Das schöne an virtuellen Methoden ist, das es egal ist wo sie liegen :) Ob nun gleiche Bibliothek oder andere ist wurscht.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

helium

Treue Seele

Beiträge: 180

Wohnort: NRW, Burscheid (nahe Köln)

  • Private Nachricht senden

10

20.04.2005, 18:03

Zitat

Hab ich da was falsch verstanden oder muss man den Desturktor nur wenn virtuelle Funktionen in der Klasse verhanden sind auch als virtuell deklarieren. Ich dachte, dass man dies mei reinvirtuellen Klassen nicht machen muss, da ja gar keine Instance davon gebildet werden kann.

Rein virtuelle Methoden sind auch virtuell!

Und den Virtuellen D'tor brauchst du z.B. in folgendem Fall:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Fehler {
   virtual voif foo () = 0;
}

class Klasse : public Fehler {
   ~Klasse () { cout << "Trallala\n";}
}

int main ()
{
   Fehler * fehler;
   fehler = new Klasse ();

   delete fehler; // kein "Trallala", da der D'tor der Basis aufgerufen wird, statt der von "Klasse" :(

}


Da Der D'tor der Derivate auch dafür sorgt, das die D'toren der Instanzvariablen aufgerufen werden kann das noch viel schlimmer werden. Stell dir vor "Klasse" hätte ein std::string als Member. Der von ihm verwendete Speicher würde ebenfalls nicht freigegeben werden. ...

Mach den D'tor virtuell, sobald eine Methode (rein) virtuell ist.
Why is 6 afraid of 7?
Because 7 8 9

Werbeanzeige