Forum: PC-Programmierung Mehrfachvererbung


von Frank der gott (Gast)


Lesenswert?

Mehrfachvererbungfür was wbrauchn man das

von John S. (linux_80)


Lesenswert?

Das haben sich die Java Erfinder auch gefragt
;-)

von Peter (Gast)


Lesenswert?

wenn dein Object z.b. 2 verschieden Interface untestützt

von Klaus W. (mfgkw)


Lesenswert?

Tiny 80 schrieb:
> Das haben sich die Java Erfinder auch gefragt
> ;-)

Daß sie es weggelassen haben, lag wohl weniger am mangelnden Sinn
als an dem Aufwand, das umzusetzen.

von Karl H. (kbuchegg)


Lesenswert?

Ich habe mit Mehrfachvererbung eine Entwicklung durchgemacht

* am Anfang wusste ich nicht wozu
* dann ein paar mal probiert und Gefallen daran gefunden
* dann in Probleme gelaufen
* Mehrfachvererbung verdammt und nicht mehr benutzt
* Auf den Interface-Trichter gekommen
* Gemerkt, dass Mehrfachvererbung mit Interfaces keine Probleme macht
* Dabei geblieben. Regel: Mehrfachvererbung nur mit Interfaces

von Klaus W. (mfgkw)


Lesenswert?

Angenommen, du hast eine Klasse Fahrzeug (Leergewicht, Gesamtmasse,
Art des Fahrwerks, ...), davon ist ein Pkw abgeleitet (zusätzlich
Sitzplätze) und ein LKW (Zuladung etc.).

Weiterhin gibt es eine Klasse Hebemaschine (Tragkraft etc), davon
abgeleitet Portalkran, Auslegerkran, etc..

Jetzt willst du einen Autokran machen.
Aber wovon ableiten? Es ist eigentlich ein LKW mit etwas dazu,
aber auch eine Hebemaschine.
Leitest du den Autokran vom LKW ab, fehlen die Sachen aus der
Klasse Hebemaschine und müssten parallel implementiert werden.
In Situationen, wo eine Hebemaschine genutzt werden kann, kann
man den Autokran dann nicht verwenden.
Leitest du ihn dagegen von der Hebemaschine ab, müssten die
LKW-Sachen neu programmiert werden und das Resultat kann nicht
als Fahrzeug verwendet werden.

Also leitet man ihn einfach von LKW und von Hebemaschine ab
und wird damit glücklich. Damit ist ein Autokran sowohl
ein LKW (und damit ein Fahrzeug) als auch eine Hebemaschine.

von Gast (Gast)


Lesenswert?

Frank der gott (Gast) wrote:

> Mehrfachvererbungfür was wbrauchn man das

braucht man nicht, siehe

"Erläuterung des Begriffs Mehrfachvererbung"

"Mehrfachvererbung ist in der Welt der objektorientierten Programmierung 
die Vererbung von mehreren Klassen gleichzeitig."

"C++: möglich
Java: nicht möglich
VB6: nicht möglich
VB.NET: nicht möglich
C#: nicht möglich"

.NET kommt auch ohne aus, also wozu der Aufwand?!

(jetzt gibt es bestimmt Mecker von den eingefleischten C++'ern :-))

von Klaus W. (mfgkw)


Lesenswert?

Natürlich kann man ohne auskommen.
Aber man kommt auch ohne OO aus, ohne ordentliches Bier
und ohne Sex.
Aber will man das?
Mehrfachvererbung vermisst man dann nicht, wenn man sie gar
nicht kennt.

Interfaces (Java) sind ein müder Abklatsch, weil ihre
Implementierung nicht vererbt wird und in jeder weiteren Ableitung
neu gestrickt werden muss - nicht ganz im OO-Sinne und nur tragbar,
wenn im Einzelfall nicht viel dahinter steckt.
Man braucht Mehrfachvererbung sicher nicht oft, aber manchmal
ist es ohne nur ein Gemurkse. Wer also nur C# und VB programmiert,
braucht es dementsprechend nicht :-)

von Nils (Gast)


Lesenswert?

> ... also wozu der Aufwand?!
Es ist doch auffällig, dass Sprachen, die Wert auf einen 
funktionierenden Garbage Collector legen, keine Mehrfachvererbung 
kennen.
In C++ sollte es Aufgabe des Entwicklers sein, den Speicher zu pflegen.
In JAVA soll der Entwickler sich nicht um solche 'Details' kümmern. Ich 
kenne auch keine etablierte Interpretersprache die das Konzept der 
Mehrfachvererbung kennt.

Klaus hat ja schon ein sinnvolles Beispiel für Mehrfachvererbung 
genannt. Ich denke, Mehrfachvererbung wird schlicht und einfach dann 
nicht implementiert, wenn man einen narrensicheren Garbage Collector für 
alle Situationen braucht.

von Karl H. (kbuchegg)


Lesenswert?

Nils schrieb:
>> ... also wozu der Aufwand?!
> Es ist doch auffällig, dass Sprachen, die Wert auf einen
> funktionierenden Garbage Collector legen, keine Mehrfachvererbung
> kennen.
> In C++ sollte es Aufgabe des Entwicklers sein, den Speicher zu pflegen.
> In JAVA soll der Entwickler sich nicht um solche 'Details' kümmern. Ich
> kenne auch keine etablierte Interpretersprache die das Konzept der
> Mehrfachvererbung kennt.
>
> Klaus hat ja schon ein sinnvolles Beispiel für Mehrfachvererbung
> genannt. Ich denke, Mehrfachvererbung wird schlicht und einfach dann
> nicht implementiert, wenn man einen narrensicheren Garbage Collector für
> alle Situationen braucht.

Den Zusammenhang kann ich nicht sehen.
Ein Garbage Collector kümmert sich um Objekte. Ob dieses Objekt jetzt 
über mehrere Vererbungspfade verfügt, ist ja fürs Objekt Jacke wie Hose. 
Objekt ist Objekt.

Aber mit Mehrfachvererbung kann man sich bitterböse ins Schwierigkeiten 
bringen, wenn die Vererbungspfade zum Vater hin wieder zusammenlaufen 
(sog. Diamond Shape Inheritance)

          A
        /   \
       /     \
     B         C
       \     /
        \   /
          D

Oder um bei Klausens Beispiel zu bleiben.

Ein LKW ist ein Kraftfahrzeug, aber auch eine Hebebühne könnte ein 
Kraftfahrzeug sein. Ist dann ein Autokran ein doppeltes Kraftfahrzeug?
(Stichwort: virtuelle Vererbung)

von Klaus W. (mfgkw)


Lesenswert?

Den Zusammenhang mit GC sehe ich auch nicht so recht, außer
darin, daß sowohl Mehrfachvererbung als auch eigene Verantwortung
für Speicherorganisation scharfe, aber auch gefährliche Werkzeuge
sind.
Viele Sprachen versuchen, ihre Anwender von Fehlern fern zu halten,
C++ ermöglicht alles, was vielleicht mal nötig ist, und zwar
so effizient wie möglich.

Man kann C++ natürlich zu Recht vorwerfen, daß vieles darin
gefährlich ist. Aber so ist das halt mit scharfem Werkzeug;
wer nicht mit Behindertenmessern arbeiten will, muß selber
zusehen, daß er sich nicht selbst die Augen öffnet.

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Den Zusammenhang mit GC sehe ich auch nicht so recht, außer
> darin, daß sowohl Mehrfachvererbung

Wenn ich mich recht erinnere, gibt es bei Mehrfachvererbung auch 
Probleme mit dem Slicing, wenn man nicht aufpasst.

> C++ ermöglicht alles, was vielleicht mal nötig ist, und zwar
> so effizient wie möglich.

Und das ist das, was ich an C++ so mag. Ich behalte in den für mich 
wichtigen Bereichen die volle Kontrolle. Und wenn beim Pofiling raus 
kommt, dass eine Klasse überdurchschnittlich oft durch new und delete 
durch muss und das dann noch signifikant zur Laufzeit beiträgt, dann 
statte ich die Klasse mit einer Poolallokierung aus und drücke so die 
Laufzeit (normalerweise) wieder in ein erträgliches Mass. Auch 
Speicherfragmentierung kann man so ziemlich wirkungsvoll begegnen.

Das alles sind für mich Gründe, warum ich das Speichermanagement so 
ungern in die Hand eines GC lege. Mit ein bischen Disziplin ist es dann 
auch gar nicht so schwer Klassen zu schreiben, die eine Resource 
dynamisch verwalten oder Reference Couting betreiben (ich weiß: bei 
Multithreading gibt das Probleme). In C++ kann ich mir mein Werkzeug 
aussuchen.

>
> Man kann C++ natürlich zu Recht vorwerfen, daß vieles darin
> gefährlich ist. Aber so ist das halt mit scharfem Werkzeug;
> wer nicht mit Behindertenmessern arbeiten will, muß selber
> zusehen, daß er sich nicht selbst die Augen öffnet.

Ein wahres Wort!

von Nils (Gast)


Lesenswert?

> Den Zusammenhang kann ich nicht sehen.
> Ein Garbage Collector kümmert sich um Objekte. Ob dieses Objekt jetzt
> über mehrere Vererbungspfade verfügt, ist ja fürs Objekt Jacke wie Hose.
> Objekt ist Objekt.

Wenn eine Sprache nur über eine Einfach-Vererbung verfügt, ist das 
Kriterium für das automatische Entfernung eines Objekts sehr simpel:
So lange noch ein Verweis auf das Objekt existiert, darf das Objekt 
nicht gelöscht werden. Existiert kein Verweis mehr, kann das Objekt 
entfernt werden. Manche Interpretersprachen zählen dazu einfach die 
Anzahl der Verweise. Einige dieser Sprachen kennen konsequenterweise 
auch keinen Destruktor.

Bei Vererbungspfaden können beliebig komplizierte Objektbäume entstehen. 
Ich denke, es ist schwierig (vielleicht sogar allgemein nicht lösbar) 
Kriterien für das automatische Löschen von Objekten zu finden. Daher 
meine Vermutung:
Interpretersprachen und Sprachen, die Bytecode erzeugen (in dem Sinne, 
dass ein Bytecode interpretiert wird) machen es sich hier einfach und 
verzichten schlicht auf die Mehrfachvererbung.

Korrigiert mich bitte, wenn ich falsch liege.

von java_fan (Gast)


Lesenswert?

Man kann auch bei Java eine eigene Speicherverwaltung verwenden.

Man holt sich den Speicher von der eigenen Speicherverwaltung im 
Konstruktor und gibt in der finilize Methode wieder frei.

Man kann bei Java auch einen "Destruktor" für bestimmte Klassen bauen. 
(einer klasse finilize methode vererben als public).

Man muss diesen "Destruktor" bei Bedarf aufrufen.

Reference Counting ist somit auch einfach und sinnvoll möglich. Man muss 
nur die Objekte von Hand entsorgen, sonst gammeln sie evtl   lange vor 
sich hin bis der GC sie "abholt".

von Nils (Gast)


Lesenswert?

>... Man muss nur die Objekte von Hand entsorgen...
Darauf wollte ich hinaus: Es gibt Sprachen, die ihr Paradigma auf den 
Schwerpunkt des automatischen Entsorgen von Objekten legen. Soweit ich 
JAVA kenne, wird dies auch hier bevorzugt.

Bei den interpretierbaren 'Server-Sprachen' ist das die Präferenz, 
ebenso bei den genannten VisualBasic-Dialekten.

von Gast (Gast)


Lesenswert?

Also ist der Garbage Collector sowas wie die Bad Bank für die 
Finanzindustrie?

:-)

von Nils (Gast)


Lesenswert?

> Also ist der Garbage Collector sowas wie die Bad Bank für die
> Finanzindustrie?
... und alle warten auf den großen Crash?
So gesehen muss Madoffs für Mehrfachvererbung in den Knast wandern.

von Rolf Magnus (Gast)


Lesenswert?

@Nils:

> Wenn eine Sprache nur über eine Einfach-Vererbung verfügt, ist das
> Kriterium für das automatische Entfernung eines Objekts sehr
> simpel:
> So lange noch ein Verweis auf das Objekt existiert, darf das Objekt
> nicht gelöscht werden.

Das ändert sich bei Mehrfachvererbung doch nicht.

@Karl heinz:

> Auch Speicherfragmentierung kann man so ziemlich wirkungsvoll
> begegnen.

Gerade das ist ein Punkt, wo ein Garbage Collector einen Vorteil haben 
kann. Da er alle Zeiger auf ein Objekt kennt bzw. ermitteln kann, ist es 
ihm möglich, Objekte während ihrer Lebenszeit im Speicher zu verschieben 
und damit den Speicher zu defragmentieren. Setzt natürlich voraus, daß 
der GC das auch macht.

@java_fan:

>Man kann bei Java auch einen "Destruktor" für bestimmte Klassen
> bauen.
> Man muss diesen "Destruktor" bei Bedarf aufrufen.

Da sehe ich den größten Nachteil von GC-Sprachen. Das gilt ja nicht nur 
für Speicher, sondern generell für alle Ressourcen. In C++ kann ich eine 
Ressource schön in einer Klasse kapseln. Wenn ich z.B. ein File-Objekt 
zerstöre, wird die Datei automatisch vom Destruktor geschlossen. Bei 
Java nicht so. Da muß ich das immer explizit machen. Deshalb gibt es bei 
Java für's exception handling auch ein "finally" und bei C++ nicht. C++ 
braucht sowas gar nicht, weil es Destruktoren gibt, die automatisch 
aufgerufen werden.
Man erkauft sich mit Java also ein automatisches Speichermangement, 
indem man sich dazu zwingen läßt, immer sämtliche anderen Ressourcen 
manuell zu verwalten.

von Mark B. (markbrandis)


Lesenswert?

Gast schrieb:
> Also ist der Garbage Collector sowas wie die Bad Bank für die
> Finanzindustrie?
>
> :-)

:o)

von (gast) (Gast)


Lesenswert?

Python unterstützt Mehrfachvererbung, wird interpretiert und hat einen 
GC.

von zwieblum (Gast)


Lesenswert?

lisp (sowohl interpretierter code als auch compilierter) hat auch 
mehrfachvererbung, nur heißts da anders, weil das standard wurde als es 
das schöne wort noch nicht gab.

das war 1980 mit dem dialekt "Flavors" :-)

von r auscher (Gast)


Lesenswert?

Ein weiteres Problem bei Mehrfachvererbung ist die Möglichkeit, dass 
zwei   Elternklassen die gleichen Eigenschaften haben können.

Z.B. bei C++ wird dann nur die Eigenschaft aus einer Klasse verwendet.

Ein Amphipienfahrzeug (Auto und Schiff) kann wie ein Auto auf der Straße 
fahren und wie ein Schiff auf dem Wasser.

von Klaus W. (mfgkw)


Lesenswert?

In C++ kann man das mit einem zusätzlichen virtual an der richtigen
Stelle steuern, wie man es haben will.

Wird eine Eigenschaft von beiden Seiten geerbt und man greift
ohne weitere Benamsung darauf zu, bekommt man einen Compilerfehler.

von Arc N. (arc)


Lesenswert?

Nils schrieb:
>> ... also wozu der Aufwand?!
> Es ist doch auffällig, dass Sprachen, die Wert auf einen
> funktionierenden Garbage Collector legen, keine Mehrfachvererbung
> kennen.
> In C++ sollte es Aufgabe des Entwicklers sein, den Speicher zu pflegen.
> In JAVA soll der Entwickler sich nicht um solche 'Details' kümmern. Ich
> kenne auch keine etablierte Interpretersprache die das Konzept der
> Mehrfachvererbung kennt.

Eine der ersten Sprachen die auf das .NET-Framework portiert wurden, war 
Eiffel. BTW auch eine der ganz wenigen Sprachen, die im Gegensatz zu 
C++, Mehrfachvererbung richtig implementieren. 1)
OCaml kennt auch Mehrfachvererbung (zum normalen System gehören sowohl 
Interpreter, als auch Bytecode-Interpreter und nativer Compiler).
Wenn man möchte, kann man auch das was Python macht, als 
Mehrfachvererbung durchgehen lassen.
Alle genannten Sprachen haben Garbage Collection.

1) einige Details der Implementation gibt's hier 
http://msdn.microsoft.com/en-us/library/ms973898.aspx

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Also ich habe schon ein paar größere Projekte mit Java umgesezt.
Und eigentlich bin ich immer mit interface+abstrakten Klassen gut dabei 
ausgekommen.
An den Stellen wo ich mir gedacht habe: Jezt wäre Mehrfachvererbung 
nützlich hat sich nach einigem Nachdenken doch herausgestellt das es 
doch anders (u.U. sogar besser) ging.

Klaus Wachtler schrieb:
> Jetzt willst du einen Autokran machen.
...
> Aber wovon ableiten? Es ist eigentlich ein LKW mit etwas dazu,
Eben es ist eigentlich ein LKW mit etwas dazu... und keine Ortsfeste 
Hebemaschine.
> aber auch eine Hebemaschine.
> Leitest du den Autokran vom LKW ab, fehlen die Sachen aus der
> Klasse Hebemaschine und müssten parallel implementiert werden.
Warum also nicht einen LKW der als zusätzliche Eigenschaft 
(Membervariable) eine Hebemaschine hat? (die Auf der Ladefläche montiert 
ist ;) )
> In Situationen, wo eine Hebemaschine genutzt werden kann, kann
dann einfach über einen Getter die Hebemaschine(neigenschaften) genuzt 
werden.

von Klaus W. (mfgkw)


Lesenswert?

Läubi .. schrieb:
> ...
> Warum also nicht einen LKW der als zusätzliche Eigenschaft
> (Membervariable) eine Hebemaschine hat? (die Auf der Ladefläche montiert
> ist ;) )
>> In Situationen, wo eine Hebemaschine genutzt werden kann, kann
> dann einfach über einen Getter die Hebemaschine(neigenschaften) genuzt
> werden.

Weil man diesxes Gebilde dann nicht z.B. in eine
std::list<Hebemaschine> einfügen kann.
Es hat nach deinem Vorschlag zwar eine Hebemaschine, ist aber keine
und darf damit halt nicht dort verwendet werden, wo man eine braucht.

Den Containern in Java ist der Typ erstmal schnurz und macht ggf. erst
zur Laufzeit Probleme, in C++ dagegen hat der Compiler den Daumen auf
dem Datentyp (ob das gut ist oder nicht, darüber kann man lange 
streiten).

(das "ortsfest" hast du dir nur im Nachhinein ausgedacht, um eine
strengere Unterteilung zu erzwingen - so streng hierarchisch ist
die Welt aber nicht immer).

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Seit Java 1.5 gibt es auch die Möglichkeit getypte Listen zu erstellen.
Die Frage ist halt warum man in die Liste den ganzen "LKW/HEBEMASCHINE" 
Combo reinstopfen will, man kann aus Objekten der Liste eh nur auf 
Eigenschaften von 'Hebemaschine' zugreifen. Also kann man im Zweifel 
auch nur die Referenz der LKW Hebemaschine da reinstecken.

> das "ortsfest" hast du dir nur im Nachhinein ausgedacht, um eine
> strengere Unterteilung zu erzwingen
Ja das stimmt, ich wollte damit nur ausdrücken das für mich in diesem 
Falle die Beiden Dinge sich in einer Grundlegenden Eigenschaft 
unterscheiden, sonst könnten sie ja auch beide von einem gemeinsammen 
Objekt abstammen.

>ob das gut ist oder nicht, darüber kann man lange
>streiten
Streiten wollte ich mich sowieso nicht, was Typprüfung angeht bin ich 
ganz klar der Verfechter von soviel Typprüfung zur Compilezeit wie 
möglich :)

von Klaus W. (mfgkw)


Lesenswert?

Tja, dann willkommen bei C++!

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:

> (das "ortsfest" hast du dir nur im Nachhinein ausgedacht, um eine
> strengere Unterteilung zu erzwingen - so streng hierarchisch ist
> die Welt aber nicht immer).

Ja, leider :-)

Auf der anderen Seite sind wir Gott sei Dank in der Situation, dass 
unsere Programme immer nur einen begrenzten Ausschnitt aus der realen 
Welt modellieren müssen, und man die Hierarchie dann oft genug noch 
sinnvoll hinbiegen kann.

Wenn ich in die Versuchung komme Mehrfachvererbung zu machen (abgesehen 
von Interfaces), dann werte ich das als Indiz, nochmal über meine 
Klassenhierarchie nachzudenken und ob sie alle Aspekte, die ich 
modellieren möchte auch hinreichend berücksichtigt. Bisher hat sich dann 
immer noch eine Alternative aufgetan.

von Klaus W. (mfgkw)


Lesenswert?

Gut, man kommt notfalls immer ohne aus.
Ebenso wie man notfalls überhaupt ohne Vererbung auskommt natürlich.

Wenn du jetzt in einem Interface aber nennenswert Code hast und
in mehreren getrennten Basisklassen nutzen  willst, dann spart
die Vererbung halt Arbeit wie jede Vererbung.
Ich sehe keinen Grund, wieso man von einer zweiten
Basisklasse/alias Interface nicht ebenso erben kann wie
von der ersten.

Das Beispiel mit dem LKW und dem Kram ist ja noch recht schlicht,
um den Mechanismus überhaupt zu erklären und damit auch leicht
angreifbar.

Tatsächlich kann es auch Fälle geben, wo die verschiedenen 
Klassen/Interfaces eines Objekts völlig verschiedene Aspekte
berühren.

Ein Beispiel ist die Serialisierbarkeit von Java.
In einer Basisklasse stecken vielleicht die eigentlichen
funktionalen Daten (Fahrzeug etc.), ein ganz anderes Thema
deckt die Serialisierbarkeit ab.
Wieder ein anderes Thema könnte von einem anderen Interface
abgedeckt werden (z.B. Informationen zum Debuggen/Profiling,
Testen,  Protokollieren).
Dadurch kann ein Objekt  je nach Blickwinkel ein Fahrzeug sein,
ein serialisierbares Objekt oder was ganz anderes; dabei
ist beim Betrachten als serialisierbares Objekt das Fahrzeug
unerheblich und kollidiert nicht.

OK, man kann sich drum rum mogeln - aber mit Mehrfachvererbung
geht es sehr elegant, ohne eben nicht.

Bei einem Interface ala Java kann ich mit dem Interface gar
nichts übernehmen, bei Mehrfachvererbung kann halt die
ganze Grundfunktionalität für alle (Fahrzeug ebenso wie
Hebemaschine im Beispiel und alle anderen Klassen) schon
vorgekaut werden.
Will man das nicht, lässt man die Klasse halt leer und ist
beim reinen Interface.
Insofern ist Mehrfachvererbung einfach ein Interface
mit mehr (optionalen) Möglichkeiten, die man nutzen kann.

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:

> Wenn du jetzt in einem Interface aber nennenswert Code hast und
> in mehreren getrennten Basisklassen nutzen  willst, dann spart
> die Vererbung halt Arbeit wie jede Vererbung.

Ooops. Hab ich das noch nicht gesagt:
Ich hab prinzipiell kein Problem mit Code in den Interfaces. Meine 
Problemkinder bei der Mehrfachvererbung waren dann zugange, wenn die 
Klassen Datenmember enthielten. Um die mach ich mittlerweile einen 
Bogen, wie der Teufel ums Weihwasser.

> Ich sehe keinen Grund, wieso man von einer zweiten
> Basisklasse/alias Interface nicht ebenso erben kann wie
> von der ersten.


Ich versuch mal ein Beispiel zu konstruieren, bei dem man in Probleme 
läuft. Ich hoffe ich kriegs noch hin :-)

von Klaus W. (mfgkw)


Lesenswert?

Die Mühe musst du dir nicht machen, schade um die Zeit!
Ich glaube dir sehr wohl, daß man in Probleme kommen kann.
Aber das kannst du auch mit Zeigern, Feldern, Funktionen,
Referenzen und Frauen.

Trotzdem sind sie halt manchmal nützlich.

von Mark B. (markbrandis)


Lesenswert?

Klaus Wachtler schrieb:
> Frauen.
>
> Trotzdem sind sie halt manchmal nützlich.

Ich hoffe, Deine Freundin/Frau liest hier nicht mit. ;-)

von Klaus W. (mfgkw)


Lesenswert?

war doch ein Lob?

von Mark B. (markbrandis)


Lesenswert?

"Man kann mit Frauen in Probleme kommen, aber manchmal sind sie ganz 
nützlich?"

Zeig mir bitte die Frau, die auf ein solches Kompliment hin mit Dir 
ausgeht :-)

von D. I. (Gast)


Lesenswert?

Mark Brandis schrieb:
> "Man kann mit Frauen in Probleme kommen, aber manchmal sind sie ganz
> nützlich?"
>
> Zeig mir bitte die Frau, die auf ein solches Kompliment hin mit Dir
> ausgeht :-)

Alles eine Frage der Konditionierung

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
>>Man kann bei Java auch einen "Destruktor" für bestimmte Klassen
>> bauen.
>> Man muss diesen "Destruktor" bei Bedarf aufrufen.
>
> Da sehe ich den größten Nachteil von GC-Sprachen. Das gilt ja nicht nur
> für Speicher, sondern generell für alle Ressourcen. In C++ kann ich eine
> Ressource schön in einer Klasse kapseln. Wenn ich z.B. ein File-Objekt
> zerstöre, wird die Datei automatisch vom Destruktor geschlossen. Bei
> Java nicht so. Da muß ich das immer explizit machen.

Naja, anders ausgedrückt: in C++ musst du jedes Objekt explizit 
freigeben, mit GC nur IO-Handles.

von Klaus W. (mfgkw)


Lesenswert?

na jedes nicht, nur die händisch allokierten.

von Rolf Magnus (Gast)


Lesenswert?

> Naja, anders ausgedrückt: in C++ musst du jedes Objekt explizit
> freigeben, mit GC nur IO-Handles.

Nein. Nur dynamisch erzeugte Objekte müssen explizit freigegeben werden, 
wobei man das auch mit Smartpointern und anderen Techniken weitgehend 
automatisieren kann. Und bei Java sind es nicht nur Dateien, um die man 
sich explizit kümmern muß, sondern generell alle Ressourcen, die kein 
Speicher sind, egal ob jetzt Window-Handles, Datenbank-Verbindungen oder 
was auch immer. In C++ muß ich mich nur um "Objekte" kümmern, unabhängig 
davon, was da drin steckt. Wenn ich ein Objekt zerstöre, werden alle 
Ressourcen freigegeben, die zum Objekt gehören. Das passt für mich 
besser in die Idee objektorientierter Programmierung und vor allem auch 
Kapselung rein, als wenn ich Speicher und andere Ressourcen immer 
getrennt betrachten muß, weil zwar der Speicher irgendwann mal 
automatisch freigegeben wird, aber andere Ressourcen, die eigentlich ein 
für mich unwichtiges Implementierungsdetail sein sollten, leider für 
immer offen bleiben.

Zu Exceptions und automatischer Freigabe mal ein kleines triviales 
Beispiel:

void lesen(const std::string& filename)
{
    std::ifstream file(filename.c_str());
    parse_header(file);
    parse_content(file);
}

In C++ wird das file-Objekt am Ende automatisch zerstört, und dabei wird 
auch automatisch die Datei geschlossen. Ich muß nichts weiter tun. Und 
das gilt auch dann, wenn eine der Funktionen eine Exception wirft. In 
Java müßte ich das Dateihandle dagegen explizit schließen, und ich muß 
auch noch explizit dafür sorgen, daß das auch beim Auftreten einer 
Exception passiert.

von Ingo E. (ogni42)


Lesenswert?

In java kann man jeder Klasse eine finalize() Methode mitgeben. Die 
entspricht einem Destruktur dahin gehend, dass sie beim Löschen des 
Objektes aufgerufen wird. Aber: Das macht der GC und der alleine 
entscheidet, wann das passiert - was theoretisch niemals sein kann.

In modernen Systmen mit vieeeel Speicher und nach wie vor nur 64k 
TCP-Ports sind dann schnell mal die Ports zu Ende obwohl der GC noch 
nicht einmal gelaufen ist.

Ergo: Als Destruktor-Ersatz ist finalize nicht zu gebrauchen. Java hat 
nichts wirklich entsprechendes.

von P. S. (Gast)


Lesenswert?

Unterm Strich muss ich als Entwickler einer grossen Applikation meine 
Resourcen im Griff haben. Da kommt es nicht mehr darauf an, ob meine 
Objekte nun auch dazu zaehlen, oder nicht. Wer Resourcen verliert, hat 
seine Applikation falsch strukturiert. Und das ist oft ein viel 
groeberer Fehler als nur die verlorene Resource. Insofern betrachte ich 
Speicherlecks sogar als willkommenen Indikator fuer logische Fehler und 
tracke sie dementsprechend regelmaessig und gruendlich. Meine 
Applikationen muessen 100% sauber runterfahren koennen, auch aus vollem 
Lauf. Wenn das geht, ist die Wahrscheinlichkeit hoch, dass ich alles im 
Griff habe. Leider sind viele Entwickler heute der Meinung, dass fuer 
das Beenden einer Applikation ein exit()-Aufruf reicht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.