eigener klassentyp im vector
-
danke, aber was meinste mit polymorphy? sprichst du hier von mehrfachvererbung?
oder meinste das ich verschiedene Objekte haben will? wahrscheinlich das letztere,
ich habe c++Referenz das Buch und da guckt ich heute mal nach ob was über diesen Vector Typ steht, aber ich glaube mich zu errinern das da nichts steht , du meinst ich komme daran nicht herum, kannst mir mal das prinzip erklären wo der unterschied zu dem ist wie ich das gemacht habe? oder einen kleinen code zeigen der verschieden objekte in zb. einer for schleife in einem vector ablegt?in Java geht das ganz einfach, das ist da selbstverständlich mit dem new operator super easy, aber hier fehlt mir der zusammenhang ein bischen.
in java ungefähr so
for (int i=0;i<5;i++){ A a=new a(); vectorB.add(a); }ich glaub der befehl heisst add oder so naja aber so ungefähr funzt es.alle objekte sind verschieden.
will das selbe jetzt nur
für c++.mfg
-
newly schrieb:
danke, aber was meinste mit polymorphy? sprichst du hier von mehrfachvererbung?
oder meinste das ich verschiedene Objekte haben will? wahrscheinlich das letztere,Polymorphier bedeutet, daß erst zur Laufzeit der tatsächliche Typ feststeht (du also verschieden Typen gemeinsam verarbeiten kannst).
in Java geht das ganz einfach, das ist da selbstverständlich mit dem new operator super easy, aber hier fehlt mir der zusammenhang ein bischen.
In Java arbeitest du auch (fast) nur mit Pointern - und mußt dich nicht weiter darum kümmern, was hinter den Kulissen mit ihnen passiert (Stichwort: Garbage Collector). In C++ verwendet man Pointer erst, wenn man sie unbedingt braucht (und dann muß man genau darauf achten, wer wann den Pointer wieder freigeben darf).
In C++ sieht dein Code etwa so aus:
for(int i=0;i<5;++i) { A a;//ohne 'new' - das Objekt wird direkt auf dem Stack angelegt ... a mit Werten füllen vectorB.push_back(a); }(push_back() speichert eine Kopie des übergebenen Objekts, also brauchst du dich nicht darum kümmern, daß a am Ende des Schleifendurchlaufs entsorgt und in der nächsten Runde wiederverwendet wird)
-
Na, dann wollen wir mal:

camper schrieb:
rüdiger schrieb:
camper schrieb:
Z2 schrieb:
selbst elementare Konstrukte wie new können werfen
können, nicht werden oder müssen. Wenn die Umgebungsparameter hinreichend bestimmt sind, kann man das aber möglicherweise ausschließen. Schließlich müssen wir Korrektheit nicht unbedingt generell abstrakt feststellen, sondern können uns auch mit einer konkreten Implementation und Umgebung zufrieden geben.
push_back ist doch dann ein idealer Kandidat für eine Exception, da vielleicht Speicher allokiert werden muss...
richtig, aber vielleicht garantiert die umgebung ja, dass das nicht passiert.
vielleicht, vielleicht auch nicht. Wer kann das schon sagen, ohne nähere Details zu kennen? new war ja nun nur als Beispiel gedacht. Letztlich kann in C++ doch so ziemlich alles werfen. Nehmen wir mal an, man würde Zeiger auf Objekte abgeleiteter Klassen in den Vector legen (ein wesentlicher Grund Pointer zu benutzen). Dieses Konzept ist erweiterbar, d.h. es können jederzeit neue Klassen hinzukommen, die wohlmöglich nicht der Kontrolle des ursprünglichen Autors unterstehen. Eine solche Klasse könnte irgendwo eine Exception werfen, selbst wenn die urspürnglichen Klassen das nicht tun.
Ok, ich weiß, das war nicht gefragt. Ich weiß auch, das diese Situation nicht zwangsläufig auftreten muß (man könnte zum Beispiel in die Dokumentation der ursprünglichen Klassen schreiben, daß sie nciht werfen dürfen). Aber das wissen wir nicht, weil wir nur dieses winzige Code-Stück gesehen haben.
Daher bin ich der Meinung, daß man, wenn möglich, eine Antwort geben sollte, die Allgemeingültigkeit besitzt, d.h. für alle möglichen Situationen und Implementierungen der relevanten Klassen gilt.
Simon2 schrieb:
Oder den threadsafen, der aber nicht performanceoptimiert ist.
Oder den performanceoptimierten, der aber schwer erweiterbar ist.Was bitte hat Performance mit Korrektheit zu tun?
Simon2 schrieb:
Auch hier nochmal: Möchtest Du einem Einsteiger exception-safety erklären (wogegen ich gar nichts habe), dann tue es auch
Nein, möchte ich eigentlich nicht. Ich glaube es nicht, daß es eine gute Idee ist, einen Einsteiger zu früh mit zuvielen komplexen Aspekten der Sprache zu belasten. Aber ich bin auch der Meinung, daß man einem Einsteiger, wenn man die Wahl zwischen einer Exception-sicheren Methode und einer nicht Exception-sicheren Methode hat, die Exception-sichere Methode an die Hand geben sollte (nebenbei bemerkt, die SmartPointer haben an dieser Stelle ja auch noch andere Vorteile als nur die Exception-Sicherheit).
Simon2 schrieb:
.. und bei einem simplen "einmal-durchlauf-Programm" auf einem modernen Betriebssystem, spricht nichts dagegen, nach einer Ausnahme den Speicher vom OS aufräumen zu lassen.
Das sehe ich etwas anders, aber meinetwegen (müssen das Thema ja nicht totreden). Das ist eigentlich auch gar nicht mein Punkt. Aber:
- was passiert, wenn im Destruktor des "leakenden" Objekts noch andere System-Resourcen freigegeben werden? System-Resourcen, die weitaus beschränkter sind als Speicher und wo bei einem einmaligen Leak bereits die verfügbaren Resourcen erschöpft sind?
- was passiert, wenn es kein simples "einmal-durchlauf-Programm" ist?
Wir wissen schließlich nicht, was der Fragesteller da gerade schreibt (auch wenn ein "einmal-durchlauf-Programm" schon wahrscheinlicher ist). Ist es wirklich klug ihm jetzt einen Code an die Hand zu geben, bei dem er später im Verlauf seines Lernprozesses feststellt, daß der es in vielen Situationen gar nicht tut? Da geben wir ihm doch lieber gleich jetzt die SmartPointer (auf Exception-Sicherheit muß man dabei ja nicht herumreiten).
-
Performancetechnisch wäre die Reihenfolge wohl besser.
for(int i=0;i<5;++i) { vectorB.push_back(A()); //ohne 'new' - das Objekt wird direkt im vector auf dem Stack angelegt // ... a mit Werten füllen über vectorB.back(); }
-
newly schrieb:
...
in java ungefähr sofor (int i=0;i<5;i++){ A a=new a(); vectorB.add(a); }...alle objekte sind verschieden.
...... instantiieren aber alle dieselbe Klasse. Ist es wirklich das, was Du willst (unterschiedliche Objektidentitäten aber identische Objektklasse) ?
Dann hat das nichts mit Polymorphie zu tun.
Die kommt erst ins Spiel, wenn Du mit Objekten unterschiedlichr Klassen (also z.B. A und
arbeiten willst. Aber das ist in C++ eigentlich nicht anders als in Java (außer, dass vector typsicher(er) ist, d.h. Du kannst nicht beliebige Objekte reinpacken).Gruß,
Simon2.
-
Z2 schrieb:
...Was bitte hat Performance mit Korrektheit zu tun?...
Die Antwort gibst Du selbst:
Z2 schrieb:
...Daher bin ich der Meinung, daß man, wenn möglich, eine Antwort geben sollte, die Allgemeingültigkeit besitzt, d.h. für alle möglichen Situationen und Implementierungen der relevanten Klassen gilt....
Mit dem Ansatz musst Du Dich auch mit Threadsafety, Performance, Portabilität, Erweiterbarkeit, ... auseinandersetzen, weil alle diese Aspekte für "... alle möglichen Situationen und Implementierungen ..." relevant sein können.
Z2 schrieb:
...
Aber ich bin auch der Meinung, daß man einem Einsteiger, wenn man die Wahl zwischen einer Exception-sicheren Methode und einer nicht Exception-sicheren Methode hat, die Exception-sichere Methode an die Hand geben sollte ...Welche Klasse der Exceptionsicherheit meinst Du (basic, no-throw oder strong guarantee) ?
Z2 schrieb:
...
Simon2 schrieb:
.. und bei einem simplen "einmal-durchlauf-Programm" auf einem modernen Betriebssystem, spricht nichts dagegen, nach einer Ausnahme den Speicher vom OS aufräumen zu lassen.
...
- was passiert, wenn im Destruktor des "leakenden" Objekts noch andere System-Resourcen freigegeben werden? System-Resourcen, die weitaus beschränkter sind als Speicher und wo bei einem einmaligen Leak bereits die verfügbaren Resourcen erschöpft sind?Gibt genug Betriebssyteme, die sich hervorragend darum kümmern.
Z2 schrieb:
...
- was passiert, wenn es kein simples "einmal-durchlauf-Programm" ist?Darüber habe ich keine Aussage getroffen.
Auf genau Folgendes will ich hinaus:Z2 schrieb:
...
Wir wissen schließlich nicht, was der Fragesteller da gerade schreibtEben ... und deswegen ist es falsch, ohne diese Kenntnis von "unkorrektem Code" zu sprechen.
Z2 schrieb:
...
Ist es wirklich klug ihm jetzt einen Code an die Hand zu geben, bei dem er später im Verlauf seines Lernprozesses feststellt, daß der es in vielen Situationen gar nicht tut?...(mal abgesehen davon, dass exception "Ausnahme" heißt und nicht "Regel"
)
Das ist also eine Frage der Didaktik, zu der Du selbst schreibst:Z2 schrieb:
...Ich glaube es nicht, daß es eine gute Idee ist, einen Einsteiger zu früh mit zuvielen komplexen Aspekten der Sprache zu belasten....
Das glaube ich auch.
Außerdem die Gegenfrage: Ist es wirklich klug, ihm ein Werkzeug in die Hand zu geben, ohne ihm zu erläutern, was es tut und warum/wann/wie man es sinnvoll einsetzt ?
Ist es klug, ihm eine Antwort zu geben auf eine Frage, die er nicht hatte und auf deren Existenz man ihn bestenfalls mit einem Einzeiler hinweist ?Gruß,
Simon2.
-
Warum man besser SmartPointer als nackte Pointer in einen Vektor legt, kann man sicherlich auch einem Anfänger erklären (z.B.: keine Gefahr das delete zu vergessen; wenn Vector ein Datenmember einer Klasse ist, funktionieren automatiscch generierten Kopier-Konstruktor und Zuweisungs-Funktionen usw.). Auf die Exceptions kann man dann mit einem Satz hinweisen und erklären, daß der Lernende sich jetzt noch nicht darum kümmern muß und ihm weitere Einzelheiten zu diesem Thema zu einem späteren Zeitpunkt begegnen werden. Ich finde das (auch aus didaktischen Gesichtspunkten) durchaus vertretbar.
-
Z2 schrieb:
Warum man besser SmartPointer als nackte Pointer in einen Vektor legt, kann man sicherlich auch einem Anfänger erklären...
Dann tu das doch einfach !

Am Besten in der FAQ ... da ist es besser aufgehoben, als jedesmal, wenn ein Anfänger nach new/delete fragt, es "nebenbei" neu zu tun.
Gruß,
Simon2.
-
Simon2 schrieb:
newly schrieb:
...
in java ungefähr sofor (int i=0;i<5;i++){ A a=new a(); vectorB.add(a); }...alle objekte sind verschieden.
...... instantiieren aber alle dieselbe Klasse. Ist es wirklich das, was Du willst (unterschiedliche Objektidentitäten aber identische Objektklasse) ?
Dann hat das nichts mit Polymorphie zu tun.
Die kommt erst ins Spiel, wenn Du mit Objekten unterschiedlichr Klassen (also z.B. A und
arbeiten willst. Aber das ist in C++ eigentlich nicht anders als in Java (außer, dass vector typsicher(er) ist, d.h. Du kannst nicht beliebige Objekte reinpacken).Gruß,
Simon2.
ja die sind alle vom selben typ, eine klasse abgeleitet von asyncsocket.
hab mir gedacht
im vector steht dann---Vector---
a
a
a
ader vector hat 4 elemte.
jedesmal wenn ein socket eine connect anfrage kriegt soll ein a erzeugt werden und im vector gespeichert werden, so das ich über dieses a mit dem clienten kommunizieren kann.wenn ich nur ein globales a habe und ein client connectet sich geht es, aber der zweite client, also ein anderer pc kann keine verbindung mehr aufbauen weil diese socket schon belegt ist ??!!?! so denke ich deswegen möchte ich die im vector ablegen.
versteht ihr wie ich das meine?
ich meine so sollte es funktionieren wenn ich das jetzt so mache wie mir hier vorgeschlagen wurde von simon2.
Vielen Dank nochmaloder soll ich nochmal code dazu posten den ich dann natürlich selektiv hiereinsetzen so das ihr nicht zuviel da ist nur das relevante eben.
mfg
-
CStoll schrieb:
newly schrieb:
danke, aber was meinste mit polymorphy? sprichst du hier von mehrfachvererbung?
oder meinste das ich verschiedene Objekte haben will? wahrscheinlich das letztere,Polymorphier bedeutet, daß erst zur Laufzeit der tatsächliche Typ feststeht (du also verschieden Typen gemeinsam verarbeiten kannst).
in Java geht das ganz einfach, das ist da selbstverständlich mit dem new operator super easy, aber hier fehlt mir der zusammenhang ein bischen.
In Java arbeitest du auch (fast) nur mit Pointern - und mußt dich nicht weiter darum kümmern, was hinter den Kulissen mit ihnen passiert (Stichwort: Garbage Collector). In C++ verwendet man Pointer erst, wenn man sie unbedingt braucht (und dann muß man genau darauf achten, wer wann den Pointer wieder freigeben darf).
In C++ sieht dein Code etwa so aus:
for(int i=0;i<5;++i) { A a;//ohne 'new' - das Objekt wird direkt auf dem Stack angelegt ... a mit Werten füllen vectorB.push_back(a); }(push_back() speichert eine Kopie des übergebenen Objekts, also brauchst du dich nicht darum kümmern, daß a am Ende des Schleifendurchlaufs entsorgt und in der nächsten Runde wiederverwendet wird)
oh sorry falsches zitat hatte ich eben genommen.
ich meinte den code von Cstoll
danke nochmals.
-
newly schrieb:
...
versteht ihr wie ich das meine?
ich meine so sollte es funktionieren wenn ich das jetzt so mache wie mir hier vorgeschlagen wurde von simon2.
...sieht OK aus.
Ich wollte nur sichergehen, dass ich Dich richtig verstanden habe - vA, weil Du im Eröffnungspost noch eine "Klasse B" erwähnst ...
Aber jetzt ist alles klar.
Gruß,
Simon2.
-
Simon2 schrieb:
newly schrieb:
...
versteht ihr wie ich das meine?
ich meine so sollte es funktionieren wenn ich das jetzt so mache wie mir hier vorgeschlagen wurde von simon2.
...sieht OK aus.
Ich wollte nur sichergehen, dass ich Dich richtig verstanden habe - vA, weil Du im Eröffnungspost noch eine "Klasse B" erwähnst ...
Aber jetzt ist alles klar.
Gruß,
Simon2.
ja weil in klasse b der vector ist der auf aufnehmen soll, deswegen.
ps, hier muss ich ja keine speicherfreigabe machen oder? ich meine benutze so dann ja nicht der new operator??!!
-
Z2 schrieb:
Na, dann wollen wir mal:

vielleicht, vielleicht auch nicht. Wer kann das schon sagen, ohne nähere Details zu kennen? new war ja nun nur als Beispiel gedacht. Letztlich kann in C++ doch so ziemlich alles werfen. Nehmen wir mal an, man würde Zeiger auf Objekte abgeleiteter Klassen in den Vector legen (ein wesentlicher Grund Pointer zu benutzen). Dieses Konzept ist erweiterbar, d.h. es können jederzeit neue Klassen hinzukommen, die wohlmöglich nicht der Kontrolle des ursprünglichen Autors unterstehen. Eine solche Klasse könnte irgendwo eine Exception werfen, selbst wenn die urspürnglichen Klassen das nicht tun.
1. wenn new ne exception wirft- was willst du dann machen?
new exceptions kannste durchrasseln lassen, an dem punkt ist eh alles verloren.
Vielleicht, wenn du hohe ziele hast, legst du um die main nen try...catch block und schreibst(sofern möglich)nen fehlerlog, aber mehr geht nicht.
Sicher, manchmal muss man wichtige resourcen freigeben, aber bis man diese resourcen kennt, hat man schon genug über exception sicherheit gelernt, im zweifelsfall wird man bei der lektüre über diese resourcen direkt mit der nase auf das problem gestoßen.
2. was machst du mit exceptions von Klassen, die du nicht kennst? du kannst ja nichtmal einschätzen, was diese exceptions bedeuten,geschweige denn sinnvoll bearbeiten.
3. wichtiger als try...catch blöcke ist exception sicherer code. Wenn ich garantieren kann, dass der status meiner Klasse unverändert bleibt, wenn eine methode aus irgendeinem grund ne exception wirft(zb weil ein polymorphes Objekt kaputt ist), ist das viel mehr wert als panisches aufräumen von resourcen. Vorallem, weil der Fehler vielleicht doch korrigiert werden kann.
-
otze spricht einen sehr wichtigen Punkt an, nämlich dass Exception-Behandlung meist nicht auf unterster Ebene im Code geschehen kann. Deshalb ist es mir auch unverständlich, warum man um alle drei Zeilen ein try-catch schreiben soll.
-
otze schrieb:
...
...Vielleicht glaubt er Dir ja - wäre schön.
Gruß,
Simon2.