C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Mysterium virtueller Destruktor

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
rudimenter
Guest





PostPosted: Sun May 23, 2004 2:44 pm    Post subject: Mysterium virtueller Destruktor Reply with quote



Hallo,

Folgende Tatsache:

Wenn man eine neue Klasse schreibt die virtuelle Methoden beinhaltet,
sollte auch der Destruktor virtuell sein.
Dies impliziert das man vorhat von dieser Klasse auch abzuleiten.
Meine Frage ist: warum kann nicht jeder Destruktor defaultmässig virtuell
sein.
Selbst wenn man keine Andere Methode der Klasse als virtuell kennzeichnet
und
noch nicht weiß ob man von der Klasse ableiten will.
Ich weiß es würde dann trotzdem eine vtable für jeden den Destruktor
angelegt. Dies geschieht jedoch zur
Compilierzeit. Mit Laufzeiteinbussen sind also nicht zu rechnen.
Der Klassenassistent des Borland C++ Builder deklariert den Destruktor
standardmäßig als virtuell.

Also wieso diese unnütze Syntax des virtuellen Destruktors. Für die
Compilerhersteller
wäre dies ein leichtes jeden Destruktor implizit als virtuell zu
kennzeichnen.

Bye

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Georg Maaß
Guest





PostPosted: Sun May 23, 2004 4:24 pm    Post subject: Re: Mysterium virtueller Destruktor Reply with quote



rudimenter wrote:
Quote:
Ich weiß es würde dann trotzdem eine vtable für jeden den Destruktor
angelegt. Dies geschieht jedoch zur
Compilierzeit.

Nein, dies geschieht zur Laufzeit. Zur Compilezeit wird lediglich der
Code generiert, der diesen VTable verwaltet. Frühestens der Linker
könnte entdecken, daß dieser VTable überflüssig ist. Selbst wenn er es
entdeckt, dann könnte es es trotzdem nur dann wegoptimieren, wenn
garantiert ist, daß das niemals von einem anderen Programm mitbenutzt
werden kann als von dem Programm, das gerade gelinkt wird. Bei DLLs und
SOs geht das nicht, weil ja jemand die fremde Komponenten als
Basisklasse für eigene Spezialisierungen verwenden könnte. Der Linker
könnte es also in der Regel nicht wegoptimieren, selbst wenn es niemals
benutzt wird. Für eine Wegoptimiermöglichkeit durch den Linker müßte der
Compiler stets beide Code-Varianten als Wahlmöglichkeit dem Linker
bereitstellen.

Quote:
Mit Laufzeiteinbussen sind also nicht zu rechnen.

Doch, ist es. Es mach doch einen Unterschied, ob ich von Florenz direkt
nach Rom laufe, oder ob ich mir immer erst in Peking einen Laufzettel
besorgen muß, um zu erfahren, daß es nach Rom geht.

Quote:
Der Klassenassistent des Borland C++ Builder deklariert den Destruktor
standardmäßig als virtuell.

Damit macht er die Klassen ohne Nachdenken polymorph ableitbar. Meistens
aber ist es besser nicht hirnlos abzuleiten, was einem vor die Flinte
kommt, sondern erst mal in das Manual zu gucken, ob das Ding überhaupt
für Polymophyzwecke abgeleitet werden will.

Quote:
Also wieso diese unnütze Syntax des virtuellen Destruktors. Für die
Compilerhersteller wäre dies ein leichtes jeden Destruktor implizit
als virtuell zu kennzeichnen.

Die Syntax ist nicht unnütz. Die Objekt-Leafs dürften wohl gegenüber den
Basis-Klassen die Mehrheit bilden. Wenn die Objekt-Leafs alle auf
Verdacht virtuell sind, dann bremst dies unnötig. Ob diese Bremse
gegenüber anderen Hemmschuhen ins Gewicht fällt, ist eine andere Frage.
Aber eine zusätzliche Bremse ist es auf jeden Fall.

--
Georg Maaß - bioshop.de D-76227 Karlsruhe, Westmarkstraße 82
HTML, XML / JavaScript, C++, Java, PHP, VB / CGI, JSP, ASP, ASP.net
- The ultimate DHTML engine: http://gml-modul.sourceforge.net -
http://sourceforge.net/projects/gml-modul

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Martin Heibel
Guest





PostPosted: Sun May 23, 2004 4:32 pm    Post subject: Re: Mysterium virtueller Destruktor Reply with quote



rudimenter wrote:

Quote:
Hallo,

Folgende Tatsache:

Wenn man eine neue Klasse schreibt die virtuelle Methoden beinhaltet,
sollte auch der Destruktor virtuell sein.
Stimmt.


Quote:
Meine Frage ist: warum kann nicht jeder Destruktor defaultmässig virtuell
sein.
Weil es manchmal unnötigen Aufwand bedeutet.


Quote:
Ich weiß es würde dann trotzdem eine vtable für jeden den Destruktor
angelegt. Dies geschieht jedoch zur
Compilierzeit. Mit Laufzeiteinbussen sind also nicht zu rechnen.
Wenn der Destruktor leer ist, kann er nicht mehr wegoptimiert werden,

Destruktoren könnten nicht mehr inline sein und wenn auf der
Laufzeitplattform indizierte Sprünge länger dauern als direkte, ist der
Aufwand auch da höher.

Quote:
Der Klassenassistent des Borland C++ Builder deklariert den Destruktor
standardmäßig als virtuell.
Ich sehe so etwas als *Anwendungs*entwickler auch als sinnvoll an, aber wenn

jemand das letzte bisschen an Performance rauskitzeln muss, dann ist er
froh um jede Optimierungsmöglichkeit. IMHO ist C++ für ein Großteil der
Anwendungsentwicklung nicht optimal, da Robustheit hierbei wichtiger ist,
als Performance. Um das Problem in den Griff zu bekommen, gewöhnt man sich
üblicherweise an, gewisse Dinge immer zu tun (wie z.B. Destruktoren
virtuell zu machen) und kommt dann auf Fragen wie Deine.

IMHO wäre es eine tolle Sache, wenn das Überschreiben nicht-virtueller
Methoden verboten wäre. Dann hätte man die volle Performance und einen
besseren Schutz vor Flüchtigkeitsfehlern. Aber das wird schon aus
Kompatibilitätsgründen nicht gemacht.

Gruß,
Martin.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Horst Kraemer
Guest





PostPosted: Sun May 23, 2004 5:10 pm    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

On Sun, 23 May 2004 16:44:23 +0200, "rudimenter" <mikepodonyi (AT) web (DOT) de>
wrote:

Quote:
Wenn man eine neue Klasse schreibt die virtuelle Methoden beinhaltet,
sollte auch der Destruktor virtuell sein.
Dies impliziert das man vorhat von dieser Klasse auch abzuleiten.
Meine Frage ist: warum kann nicht jeder Destruktor defaultmässig virtuell
sein.
Selbst wenn man keine Andere Methode der Klasse als virtuell kennzeichnet
und
noch nicht weiß ob man von der Klasse ableiten will.
Ich weiß es würde dann trotzdem eine vtable für jeden den Destruktor
angelegt. Dies geschieht jedoch zur
Compilierzeit. Mit Laufzeiteinbussen sind also nicht zu rechnen.

Die vtable wird zur Linkzeit generiert - aber das zähltest Du wohl zur
Compilierzeit. Die Laufzeiteinbuße gibt es natürlich, denn sobald Du

class MyClass {
public:
virtual ~Myclass() {};
} *p = new MyClass;
...
delete p;

schreibst, wird der d'tor nicht statisch eingesetzt - wie es bei einem
nicht-virtuellen d'tor der Fall wäre -, sondern er wird über den
vtable-Zeiger des Objekts, auf das p zeigt, angesprungen.
Das mag verschmerzbar bis irrelevant sein, aber einer der Grundsätze
von C++ ist, dass Du nur das bezahlen mußt, was Du bestellt hast. Und
daher ist der Default-c'tor lt. Standard der Programmiersprache C++
eben nicht-virtuell.

--
Horst

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Georg Maaß
Guest





PostPosted: Sun May 23, 2004 5:10 pm    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

Martin Heibel wrote:
Quote:
IMHO wäre es eine tolle Sache, wenn das Überschreiben nicht-virtueller
Methoden verboten wäre. Dann hätte man die volle Performance und einen
besseren Schutz vor Flüchtigkeitsfehlern. Aber das wird schon aus
Kompatibilitätsgründen nicht gemacht.

Das ist nicht nötig. Es reicht völlig aus, wenn Dir klar ist, daß die
Zuweisung einer abgeleiteten Instanz an eine Basisklasse mit nicht
virtuellen Destruktor nicht polymorph ist. Die Basisklasse darf daher
nicht zerstört werden, sondern die abgeleitete Klasse muß zerstört werden.

Bei Referenzen sollte es da keine Probleme geben, weil sie ja
normalerweise nicht in einem anderen Scope zerstört werden, als sie
angelegt wurden. Aber bei Zeigern kann ein delete auf Basisklasse* zu
einem Problem füren, wenn es sich in Wahrheit um ein Abgeleiteteklasse*
handelt, was das delete nicht erkennen kann, wenn der Destruktor nicht
virtuell ist. Du hättest dann also wahrscheinlich einen halbtoten Zombie
im Keller.

--
Georg Maaß - bioshop.de D-76227 Karlsruhe, Westmarkstraße 82
HTML, XML / JavaScript, C++, Java, PHP, VB / CGI, JSP, ASP, ASP.net
- The ultimate DHTML engine: http://gml-modul.sourceforge.net -
http://sourceforge.net/projects/gml-modul

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
rudimenter
Guest





PostPosted: Sun May 23, 2004 6:33 pm    Post subject: Re: Mysterium virtueller Destruktor Reply with quote


"Georg Maaß" <georg (AT) bioshop (DOT) de> schrieb im Newsbeitrag
news:2hc1b5Fatrg3U1 (AT) uni-berlin (DOT) de...
Quote:
rudimenter wrote:
Ich weiß es würde dann trotzdem eine vtable für jeden den Destruktor
angelegt. Dies geschieht jedoch zur
Compilierzeit.

Nein, dies geschieht zur Laufzeit. Zur Compilezeit wird lediglich der
Code generiert, der diesen VTable verwaltet.

Ja, sorry mein Fehler.

Quote:
Frühestens der Linker
könnte entdecken, daß dieser VTable überflüssig ist. Selbst wenn er es
entdeckt, dann könnte es es trotzdem nur dann wegoptimieren, wenn
garantiert ist, daß das niemals von einem anderen Programm mitbenutzt
werden kann als von dem Programm, das gerade gelinkt wird. Bei DLLs und
SOs geht das nicht, weil ja jemand die fremde Komponenten als
Basisklasse für eigene Spezialisierungen verwenden könnte.

Hier verstehen wir uns falsch.
Beispiel:
Der Compiler nimmt an das alle Destruktoren virtuell sind.
Der Linker Prüft die einzelnen obj-Files und kann hier herausfinden ob
Verbung
(innerhalb des Progamms) stattfindet. Wenn Ja dann lasse es virtuell,
wenn Nein dann weg damit. Der Linker weiß auch ob Klassen exportiert werden.
Wenn Klasse exportiert wird dann lasse virtuell, wenn Nein dann weg damit.

Vielleicht stelle ich mir das zu simpel vor.

Quote:
Damit macht er die Klassen ohne Nachdenken polymorph ableitbar. Meistens
aber ist es besser nicht hirnlos abzuleiten, was einem vor die Flinte
kommt, sondern erst mal in das Manual zu gucken, ob das Ding überhaupt
für Polymophyzwecke abgeleitet werden will.

Da verstehen wir uns

Quote:
Die Syntax ist nicht unnütz. Die Objekt-Leafs dürften wohl gegenüber den
Basis-Klassen die Mehrheit bilden. Wenn die Objekt-Leafs alle auf
Verdacht virtuell sind, dann bremst dies unnötig.

siehe: "Hierverstehen uns wir falsch"

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
James Kanze
Guest





PostPosted: Sun May 23, 2004 7:19 pm    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

"rudimenter" <mikepodonyi (AT) web (DOT) de> writes:

Quote:
Folgende Tatsache:

Wenn man eine neue Klasse schreibt die virtuelle Methoden
beinhaltet, sollte auch der Destruktor virtuell sein. Dies
impliziert das man vorhat von dieser Klasse auch abzuleiten. Meine
Frage ist: warum kann nicht jeder Destruktor defaultmässig
virtuell sein.

Zwei grosse Grunde:

- Das Ergebnis wäre nicht C-kompatibel. Vergiss nicht, dass in C++
struct und class sind in Grunde genommen dieselben Sachen.

- Es wäre nie möglich, eine Struktur statisch zu initialisieren.
Eine Klasse, die eine virtuelle Funktion enthält, hat nie einen
trivialen Konstruktor noch Destruktor.

Quote:
Selbst wenn man keine Andere Methode der Klasse als virtuell
kennzeichnet und noch nicht weiß ob man von der Klasse ableiten
will. Ich weiß es würde dann trotzdem eine vtable für jeden
den Destruktor angelegt. Dies geschieht jedoch zur Compilierzeit.

Es wird nicht nur eine vtable angelegt, sondern einen vptr in jeden
Instanzen initialisiert. Diese Initialisierung findet beim
Programmablauf statt, und ist der Grund, warum Klassen mit virtuellen
Funktionnen keine trivialen Konstructor und Destruktor haben.

Quote:
Mit Laufzeiteinbussen sind also nicht zu rechnen.

Mit Laufzeiteinbussen ist wohl ein bisschen mit zu rechnen. Aber das ist
nicht das wichtigste (obwohl für ganz kleine Klassen spielt es auch
eine Rolle). Einige andere bedeutende Unterschiede:

- Aus den include-Datei netdb.h (Linux):

#ifdef __cplusplus
extern "C" {
#endif
struct hostent
{
char *h_name; /* Official name of host. */
char **h_aliases; /* Alias list. */
int h_addrtype; /* Host address type. */
int h_length; /* Length of address. */
char **h_addr_list; /* List of addresses from name server. */
};
#ifdef __cplusplus
}
#endif

Es ist nur ein Beispiel ausser viele. Ähnliches gibt's bei fast
jeden OS. Es funktionniert nur deshalb, weil C und C++ dieselben
Auslegung von Strukturen benutzen. Und insbesonders, weil C++ keine
vptr zufügt.

- Ich benutze häufig etwas wie folgt:

typedef std::map< std::string, std::string >
Map ;

struct Elem
{
char const* key ;
char const* value ;

operator Map::value_type() const
{
return Map::value_type( key, value ) ;
}
} ;
static Elem const initialValues[] =
{
{ "key1", "value1" },
// ...
} ;

std::map< std::string, std::string > const&
getMap()
{
static std::map< std::string, std::string > const
theInstance( begin( initialValues ),
end( initialValues ) ) ;
return theInstance ;
}

Ich kann getMap auch vom Konstruktor eines statischen Objektes
aufrufen. Ohne Risiko vor einer unangemessen
Initialisierungsreihenfolge; es ist 100% garantiert, dass
initialValues bevor alle dynamischen Initialisierungen initialisiert
wird. Aber nur deshalb, weil ich habe dafür gesorgt, das Elem
eine POD-Struktur ist, was nicht möglich wäre, wenn Elem eine
virtuelle Funktion hätte.

- Es geht nicht nur um Laufzeit, sondern auch um Platz. Auf meinem
Rechner:

struct Color
{
unsigned char red ;
unsigned char green ;
unsigned char blue ;
} ;

hat eine Große von 3; mit einem virtuellen Destruktor hat er eine
Große von 8. Wenn ich einen Abbild von 1000x1200 Elementen, dass
macht was aus, wenn es geht um die Speicherbenutzung. Une wenn ich
es anlege, und muss alle 1200000 vptr initialisieren, dass macht
auch was aus um die Laufzeit. Also: wie es jetzt ist, habe ich eine
Array von 3,6 MB, deren Initialisierung auf unbestimmten Werten Nul
kostet; mit pflichtmäßigen virtuellen Destruktoren habe ich
eine Array von 8 MB, und muss 1200000 Zieger bei der Initialisierung
schreiben. (Die Laufzeit Unterschied mag noch größer sein, als
es am ersten Blick erscheint. Denk mal an den virtuallen Speicher,
und die Tatsache, dass bei der Initialisierung der vptr, ich muss in
jedes einzelne Element schreiben.)

Quote:
Der Klassenassistent des Borland C++ Builder deklariert den
Destruktor standardmäßig als virtuell.

Welcher Art von Klassen generiert er? Es gibt Anwendungsgebiete (wie zum
Beispiel GUI-Komponenten), wo das durchaus sinnvoll ist. Aber nicht
überall.

Quote:
Also wieso diese unnütze Syntax des virtuellen Destruktors.
Für die Compilerhersteller wäre dies ein leichtes jeden
Destruktor implizit als virtuell zu kennzeichnen.

Für die Compilerhersteller wäre es sicher kein Problem. Für den
Benutzer der Sprache dagegen wohl.
--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Helmut Zeisel
Guest





PostPosted: Mon May 24, 2004 6:50 am    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

rudimenter wrote:

Quote:
Dies impliziert das man vorhat von dieser Klasse auch abzuleiten.
Meine Frage ist: warum kann nicht jeder Destruktor defaultmässig virtuell
sein.
Selbst wenn man keine Andere Methode der Klasse als virtuell kennzeichnet
und
noch nicht weiß ob man von der Klasse ableiten will.

Bjarne Stroustrup hat vorgeschlagen, dass in C++0x der Destructor fuer
Klassen mit virtuellen Fct automatisch ebenfalls virtuell sein soll:

Bjarne Stroustrup: Directions for C++0x

http://www.research.att.com/~bs/C++0x_panel.pdf

Remove embarrassments
- Frequent questions, frequent novice errors
..) a vector and a string that are range checked by default
..) Prohibit default copying of objects with destructors
..) Give a class with virtual functions a virtual destructor by default

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Markus Breuer
Guest





PostPosted: Mon May 24, 2004 7:37 am    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

Georg Maaß schrieb:

Quote:
rudimenter wrote:

Der Klassenassistent des Borland C++ Builder deklariert den Destruktor
standardmäßig als virtuell.

Damit macht er die Klassen ohne Nachdenken polymorph ableitbar. Meistens
aber ist es besser nicht hirnlos abzuleiten, was einem vor die Flinte
kommt, sondern erst mal in das Manual zu gucken, ob das Ding überhaupt
für Polymophyzwecke abgeleitet werden will.


Weitere Anmerkung:

Der Klassenassistent wird in erste Linie dazu verwendet, um von TOBject
und seinen Nachfahren abzuleiten. Der Borland C++ Builder ist sehr
VCL-lastig und implementiert zudem nicht c++ konforme Erweiterungen,
etwa __published:.
Da VCL-Formulare eher selten instanziert werden, deault ist einmal beiom
Programmstart, dürfte ein Overhead durch virtuelle Funktionen kaum eine
Rolle spielen. Anders sieht es aus, wenn dein neuer Highspeed
Algorithmus überflüssigerweise vir. Methoden besitzt.

Gruß Markus

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Olaf Krzikalla
Guest





PostPosted: Mon May 24, 2004 9:05 am    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

Hi,

rudimenter schrieb:
Quote:
Beispiel:
Der Compiler nimmt an das alle Destruktoren virtuell sind.
Der Linker Prüft die einzelnen obj-Files und kann hier herausfinden ob
Verbung
(innerhalb des Progamms) stattfindet.
Definiere 'innerhalb des Progamms'! Wo ziehst Du die Grenzen? Wo beginnt

z.B. der IE und wo endet Windows? Sind IE-Plugins noch 'innerhalb des
Progamms'?

Quote:
Wenn Klasse exportiert wird dann lasse virtuell, wenn Nein dann weg damit.
Wenn ich in einer DLL einige mathematische Grundfunktionen

zusammengefaßt habe, dann würd ich mich aber bedanken, wenn für jeden
Vektor (bestehend aus 3 double's) ein virtueller Destruktor aufgerufen
wird (der i.Allg. nicht geinlinet werden kann und dann ständig von
außerhalb in die DLL [über VTBL & DLL-Sprungtabelle!) gesprungen wird,
nur um nichts zu tun).

Quote:
Vielleicht stelle ich mir das zu simpel vor.
Ja.


Etwas anderes ist ein implizit virtueller d'tor, wenn mindestens eine
andere Funktion virtuell ist. Über dieses Sprachfeature wird tatsächlich
ernsthaft nachgedacht.

MfG
Olaf Krzikalla

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Andre
Guest





PostPosted: Mon May 24, 2004 9:14 am    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

Georg Maaß schrieb:

Quote:
Bei Referenzen sollte es da keine Probleme geben, weil sie ja
normalerweise nicht in einem anderen Scope zerstört werden, als sie
angelegt wurden. Aber bei Zeigern kann ein delete auf Basisklasse* zu
einem Problem füren, wenn es sich in Wahrheit um ein Abgeleiteteklasse*
handelt, was das delete nicht erkennen kann, wenn der Destruktor nicht
virtuell ist. Du hättest dann also wahrscheinlich einen halbtoten Zombie
im Keller.

Wenn ich eine Klasse mit einem virtuell Destructor habe und eine Klasse

erbt von dieser, muß dann nicht auch die Kind Klasse die Arbeit des
Destructors der Elternklasse übernehmen, weil dieser ja virtuell ist und
nicht mehr aufgerufen wird ?

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Martin Winkler
Guest





PostPosted: Mon May 24, 2004 9:34 am    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

Andre wrote:
Quote:
Wenn ich eine Klasse mit einem virtuell Destructor habe und eine Klasse
erbt von dieser, muß dann nicht auch die Kind Klasse die Arbeit des
Destructors der Elternklasse übernehmen, weil dieser ja virtuell ist und
nicht mehr aufgerufen wird ?

Er _wird_ aufgerufen. Du kannst es nicht mal verhindern.

Gruß
Martin

--
http://www.jumli.de
http://www.jumlidev.de/forum/

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Stefan Reuther
Guest





PostPosted: Mon May 24, 2004 5:10 pm    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

Hallo,

rudimenter wrote:
^^^^ da fehlt ein bisschen was.
Quote:
"Georg Maaß" <georg (AT) bioshop (DOT) de> schrieb im Newsbeitrag
Frühestens der Linker
könnte entdecken, daß dieser VTable überflüssig ist. Selbst wenn er es
entdeckt, dann könnte es es trotzdem nur dann wegoptimieren, wenn
garantiert ist, daß das niemals von einem anderen Programm mitbenutzt
werden kann als von dem Programm, das gerade gelinkt wird. Bei DLLs und
SOs geht das nicht, weil ja jemand die fremde Komponenten als
Basisklasse für eigene Spezialisierungen verwenden könnte.

Hier verstehen wir uns falsch.
Beispiel:
Der Compiler nimmt an das alle Destruktoren virtuell sind.
Der Linker Prüft die einzelnen obj-Files und kann hier herausfinden ob
Verbung
(innerhalb des Progamms) stattfindet.

In der Theorie wäre das möglich, ja.

In der Praxis gibt es solche Linker nicht in nennenswerter Stückzahl.
Ich hab mal in einem Spielzeugprojekt einen Linker gebaut, der die
Erzeugung der vtbls übernommen hat und damit unbenutzte virtuelle
Funktionen eliminieren konnte. Aber in der Echten Welt[tm] ist ein
Linker eben dumm: er bekommt einfach nur eine Anzahl 'sections' oder
'Segmente', die er zu einem hübschen Executable arrangiert und Verweise
auf Symbolnamen auflöst. Neuere Modelle können dann noch Dinge wie
'linkonce'-Abschnitte, damit Template-Instanzen einfacher gehandhabt
werden können.

Aber schon für das Erzeugen einer vtbl muss der Linker mehr können als
nur Sections zusammenstecken: er muss nämlich in der Lage sein, Aufrufe
zu Funktionen über die vtbl zu erkennen. Gängige Objekt-Datei-Formate
(OMF, ELF) geben das einfach nicht her.

Um virtuelle Aufrufe in 'statische' Aufrufe umwandeln zu können, muss
der Linker sogar den Code modifizieren. Bei x86 müsste er eine
Maschinencode-Sequenz wie
mov ecx, [ebx]
call [ecx+8]
in
call funktion__Klasse
umwandeln.

Quote:
Vielleicht stelle ich mir das zu simpel vor.

Ja :-)

In der Praxis setzt man dann wohl eher so schicke Refactoring-Tools ein.


Stefan

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rolf Magnus
Guest





PostPosted: Thu May 27, 2004 8:31 pm    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

Andre wrote:

Quote:
Georg Maaß schrieb:

Bei Referenzen sollte es da keine Probleme geben, weil sie ja
normalerweise nicht in einem anderen Scope zerstört werden, als sie
angelegt wurden. Aber bei Zeigern kann ein delete auf Basisklasse* zu
einem Problem füren, wenn es sich in Wahrheit um ein
Abgeleiteteklasse* handelt, was das delete nicht erkennen kann, wenn
der Destruktor nicht virtuell ist. Du hättest dann also
wahrscheinlich einen halbtoten Zombie im Keller.

Wenn ich eine Klasse mit einem virtuell Destructor habe und eine
Klasse erbt von dieser, muß dann nicht auch die Kind Klasse die Arbeit
des Destructors der Elternklasse übernehmen, weil dieser ja virtuell
ist und nicht mehr aufgerufen wird ?

Nein. Der wird trotzdem aufgerufen. Die abgeleitete Klasse kann die
Arbeit ja gar nicht übernehmen, wenn man die Basisklasse
"ordnungsgemäß" kapselt.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Horst Kraemer
Guest





PostPosted: Fri May 28, 2004 8:12 am    Post subject: Re: Mysterium virtueller Destruktor Reply with quote

On Mon, 24 May 2004 11:14:05 +0200, Andre <a.kullmann (AT) gmx (DOT) de> wrote:

Quote:
Wenn ich eine Klasse mit einem virtuell Destructor habe und eine Klasse
erbt von dieser, muß dann nicht auch die Kind Klasse die Arbeit des
Destructors der Elternklasse übernehmen, weil dieser ja virtuell ist und
nicht mehr aufgerufen wird ?

Nein. Ein Destruktor C:~C ist immer nur fuer den Teil des C-Objekts
zustaendig, der nicht bereits seinem Vater (oder seinen Vaetern bei
Mehrfachvererbung) angehoert. Bei der Zerstoerung eines Objekts einer
Klasse werden rekursiv immer alle Destruktoren aller Vaterklassen
aufgerufen.

Wenn Du also eine Objektfamilie A->B->C hast, dann wird beim
Zerstoeren eines C-Objekts implizit immer

~C();
~B();
~A();

ausgefuehrt. D.h. ein Aufruf von C::~C sieht so aus, als uebernehme er
die Aufgaben von ~B() und ~A(), aber das liegt einfach daran, dass er
nie isoliert ausgefuehrt wird, sondern automatisch die Ausfuehrung
aller d'tors seiner Vaterklassen nach sich zieht.

Die Tatsache, dass der d'tor von A (und damit auch die von B und C)
virtuell ist, beeinflusst dies in keiner Weise. Es bewirkt nur, dass
bei

A*p = new C;

delete p;

nicht ~A(), sondern C~() (gefolgt von ~B() gefolgt von ~A())
aufgerufen wird. Die Aufgaben der Destruktoren bleiben davon
unberuehrt. Jeder ist nur fuer seine "Schale" der Objektzwiebel
zustaendig.

--
Horst

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.