Forum: PC-Programmierung Allgemeine Frage zu Iteratoren C++


von helpme91 (Gast)


Lesenswert?

Hallo,

ich habe eine allgemeine Frage an euch.
Wenn ich eine STL Liste verwende, benötige ich ja einen Iterator um mit 
der Liste was machen zu können.

Bei vector Listen, benötige ich aber keinen Iterator. Die kann ich ohne 
Iterator verwenden.

Stimmt das so?

: Verschoben durch Admin
von Zombie (Gast)


Lesenswert?

helpme91 schrieb:
> Bei vector Listen, benötige ich aber keinen Iterator. Die kann ich ohne
> Iterator verwenden.

> Stimmt das so?

Du meinst wegen dem operator[]? Ja, bei std::vector kann man Elemente 
direkt mit dem Index ansprechen (Bei std::deque übrigens auch.)

Aber auf was willst du hinaus?

von helpme91 (Gast)


Lesenswert?

Ich Frage, da ich einen Beitrag gelesen habe wo gesagt wurde, das man 
bei vector Listen grundsätzlich ohne Iterator arbeitet. Bei STL Listen 
verwendet man aber einen Iterator.

Wollte nur mal nachfragen, ob das so Stimmt.

von g457 (Gast)


Lesenswert?

> Ich Frage, da ich einen Beitrag gelesen habe wo gesagt wurde, das man
> bei vector Listen grundsätzlich ohne Iterator arbeitet.
> Bei STL Listen verwendet man aber einen Iterator. Wollte nur mal
> nachfragen, ob das so Stimmt.

Das ist natürlich nicht richtig. Und std::vector ist keine Liste.

von helpme91 (Gast)


Lesenswert?

Was ist dann richtig?

von Klaus W. (mfgkw)


Lesenswert?

Richtig ist erstens: std::vector ist ein Vektor (keine Liste), std::list 
ist eine Liste (kein Vektor).

Zweitens kann man über die Elemente einer Liste nur mit iterator 
iterieren, bei einem vector kann man zwischen iterator und einem Zugriff 
über den Index wählen (at() oder []).

Will man bei einem vector alle Elemente anfassen und die interne 
Reihenfolge ist ok, wird meist der iterator richtig sein. Sonst halt 
nicht.
Wenn man den direkten Zugriff gar nicht braucht, ist meistens 
std::vector die falsche Wahl gewesen, und std::set oder std::list wäre 
besser.

(Abgesehen davon gibt es auch const-Iteratoren, wenn man die Elemente 
nicht ändern will.)

von abc (Gast)


Lesenswert?

Alle Container der stl verwenden / haben iteratoren.

Was du vllt meinst ist ein normales Array? Das hat natürlich keine 
iteratoren.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

helpme91 schrieb:
> Was ist dann richtig?

Alle Standard Container haben Iteratoren, auch std::vector. Der wird 
typischerweise bei Standard-Algorithmen wie std::sort verwendet, z.B:
1
std::vector<int> v;
2
std::sort (v.begin(), v.end ());

Ohne Iterator kann man std::sort nicht benutzen. Selbst C-Arrays haben 
Iteratoren, und deren Typ ist einfach ein Zeiger auf das Element, diesen 
kann man ebenso an std::sort & Co übergeben. Die Range for loop benutzt 
die Iteratoren ebenfalls (implizit).

Bei vector kann man die Elemente zusätzlich auch ohne Iterator 
zugreifen, über den Index. Aber den Iterator braucht es eben trotzdem 
für die Algorithmen.

Und ein vector ist keine Liste, sondern ein kontinuierlicher 
Speicherbereich.

Klaus W. schrieb:
> Wenn man den direkten Zugriff gar nicht braucht, ist meistens
> std::vector die falsche Wahl gewesen, und std::set oder std::list wäre
> besser.

Das kann man so pauschal nicht sagen. std::list hat einen signifikanten 
Overhead aufgrund der verteilten Speichernutzung. Daher ist std::vector 
in sehr vielen Fällen doch überlegen, obwohl man den Index-basierten 
Zugriff gar nicht braucht.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

helpme91 schrieb:
> Bei vector Listen, benötige ich aber keinen Iterator. Die kann ich ohne
> Iterator verwenden.

Alle C++-Standardcontainer bieten Iteratoren, und alle, bei denen das 
sinnvoll ist, bieten einen operator[] und eine Methode at() zum Zugriff 
per Index. Nutzen kannst du immer alles, was vorhanden ist.

Oliver

: Bearbeitet durch User
von Philip S. (phs)


Lesenswert?

helpme91 schrieb:
> Was ist dann richtig?

Viele Wege führen nach Rom 😉

Wenn Du Deinen Algorithmus auf Iteratoren aufbaust, dann kannst Du den 
Container wechseln, ohne den Algorithmus anpassen zu müssen. So wird es 
in der STL gemacht.

Algorithmus bezeichnet hier den Teil Deiner Software, der die Daten in n 
der Liste bzw. im Vector verwendet. Container ist die Liste, Vektor oder 
sonstige Datenstrukturen.

Verschiedene Container haben unterschiedliche Eigenschaften: So kann 
beim Vektor in konstanter Zeit (also unabhängig der gespeicherten 
Datenmenge) auf zufällige Elemente zugegriffen werden (über den [] 
Operator). Das kann die Liste nicht. Dafür kann das Hinzufügen von 
Elementen beim Vektor länger dauern; hier arbeitet die Liste in 
konstanter Zeit.

In der Praxis: Wenn Du nur über alle Elemente eines Vektors drüber gehen 
willst, dann ist es völlig egal ob Du über Iteratoren oder [] gehst. 
Ersteres ist vielleicht etwas mehr C++ Stil; letzteres mehr C-artig.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Geht auch "ohne Iterator":
1
STL_OBJECT<TYPE> items;     // vector, list, map ... of TYPE
2
3
for(auto item : items) {
4
  item.foo();
5
}

Bei std::map natürlich zuerst auf dem map-objekt operieren:
1
for(auto item : items) {
2
  TYPEf first = item.first;
3
  TYPEs second = item.second;
4
}

Für Optimierung bei STL: wo möglich "const &" verwenden.

: Bearbeitet durch User
von helpme91 (Gast)


Lesenswert?

o.k,danke.

Eien Frage noch, wie ruft man eine Methode einer Klasse mit einem 
Iterator einer Liste auf?

von helpme91 (Gast)


Lesenswert?

Also einen polymorphen Zugriff.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Random .. schrieb:
> Geht auch "ohne Iterator":

Eben nicht, wenn das Stl-Objekt keinen Iterator hätte ginge das nicht. 
Hier wird eine versteckte Variable für den Iterator angelegt.

helpme91 schrieb:
> Eien Frage noch, wie ruft man eine Methode einer Klasse mit einem
> Iterator einer Liste auf?
1
Iterator->Funktion ();

In C++ heißt es Member-Funktion, "Methode" sagt man bei Java.

helpme91 schrieb:
> Also einen polymorphen Zugriff.

Polymorphie hat nichts mit Iteratoren zu tun.

von Klaus W. (mfgkw)


Lesenswert?

helpme91 schrieb:
> Eien Frage noch, wie ruft man eine Methode einer Klasse mit einem
> Iterator einer Liste auf?

meiniterator->methode()

*meiniterator ist das Element, und (*meiniterator).methode() wäre der 
Aufruf der Methode für das Element.
p->sub... ist dann wie bei Zeigern die Abkürzung für (*p).sub...

: Bearbeitet durch User
von Klaus W. (mfgkw)


Lesenswert?

helpme91 schrieb:
> Also einen polymorphen Zugriff.



Polymorph und STL-Container ist so eine Sache...

Falls du in der Liste bzw. Vektor verschiedene voneinander abgeleitete 
Typen haben willst, wird es komplizierter.
Die passen nämlich nicht in lauter gleichartige Elemente des Containers 
(ein abgeleitetes Irgendwas kann ja größer sein als ein Element der 
Basisklasse).

Dann müsstest du sowas wie shared_ptr<meineElementKlasse> im Container 
speichern statt der Elemente direkt (std::vector< shared_ptr< 
meineElementKlasse > >).
Beim Zugriff auf ein Element dann entsprechend eine Indirektion mehr 
einbauen als im Beispiel oben, weil *meinIterator ja jetzt nicht die 
Daten liefert, sondern den shared_ptr darauf.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

In 95% der Fälle eher unique_ptr statt shared_ptr ...

von Klaus W. (mfgkw)


Lesenswert?

Sind die 95% belastbar, oder darf ich die anzweifeln? :-)

Sonst gebe ich dir meistens recht...

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Klaus W. schrieb:
> Sind die 95% belastbar, oder darf ich die anzweifeln? :-)

Klar, ich habe da so eine Statistik... Spaß beiseite, shared_ptr braucht 
es nur in speziellen Situationen und erfordert einiges Nachdenken zur 
korrekten Anwendung. Bei unique_ptr ist einiges einfacher und klarer, 
und es ist eben sehr oft ausreichend. Dazu kommt der nicht geringe 
Overhead von shared_ptr für die Referenzzählung, die ja auch 
threadsicher sein muss.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Niklas G. schrieb:
> Random .. schrieb:
>> Geht auch "ohne Iterator":
>
> Eben nicht, wenn das Stl-Objekt keinen Iterator hätte ginge das nicht.
> Hier wird eine versteckte Variable für den Iterator angelegt.

Deshalb die Anführungszeichen :-)

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Klaus W. schrieb:
> Polymorph und STL-Container ist so eine Sache...
>
> Falls du in der Liste bzw. Vektor verschiedene voneinander abgeleitete
> Typen haben willst, wird es komplizierter.
> Die passen nämlich nicht in lauter gleichartige Elemente des Containers
> (ein abgeleitetes Irgendwas kann ja größer sein als ein Element der
> Basisklasse).

Funktioniert wunderbar, solange der Container Elemente der Basisklasse 
aufnimmt. Mit virtuellen Funktionen (oder Prototypen) lässt sich auf 
diese Weise problemlos der Call in spezielle Handler realisieren, z.B. 
das Zeichnen verschiedener Objekte.

Also:
1
class BASE {
2
  virtual Draw() = 0;
3
}
4
5
class A : public BASE {
6
  virtual Draw();
7
}
8
class B : public BASE {
9
  virtual Draw();
10
}
11
12
list<BASE> items;

Braucht man ein einzelnes Objekt, muss man entweder wissen, was drin 
ist, oder das Ganze per dynamic_cast<A>(obj) testen.

Kommen allerdings Template-Objekte der erbenden Klassen ins Spiel, wird 
das ganze etwas komplizierter. Dafür muss man ggf. über eine generische 
Zwischenklasse gehen und das template-Objekt in einem Member speichern, 
welches dann über virtuelle Funktionen der Basisklasse wiederum 
generisch behandelt werden kann.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Random .. schrieb:
1
list<BASE> items;

Das funktioniert nicht. So kann man nur Objekte der Klasse "BASE" in 
die Liste einfügen, aber nicht die abgeleiteten, denn dafür ist ggf. 
nicht genug Speicher. Es braucht einen Pointer, idealerweise als 
unique_ptr oder shared_ptr. In Java geht es direkt, aber da ist ja fast 
alles ein "Pointer".

: Bearbeitet durch User
von Random .. (thorstendb) Benutzerseite


Lesenswert?

Niklas G. schrieb:
> Random .. schrieb:
>
>
1
list<BASE> items;
>
> Das funktioniert nicht. So kann man nur Objekte der Klasse "BASE" in
> die Liste einfügen, aber nicht die abgeleiteten, denn dafür ist ggf.
> nicht genug Speicher. Es braucht einen Pointer, idealerweise als
> unique_ptr oder shared_ptr. In Java geht es direkt, aber da ist ja fast
> alles ein "Pointer".

Stimmt, zugegeben, dieses Detail hatte ich vergessen. Hat sich doch ein 
Fehler eingeschlichen :-)
Leider kann man hier nicht editieren.

Also: Meine Beispiele gelten für POINTER auf Klassen verschiedenen Typs 
gemeinsamer Basisklasse!

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Niklas G. schrieb:
> Das funktioniert nicht. So kann man nur Objekte der Klasse "BASE" in
> die Liste einfügen, aber nicht die abgeleiteten, denn dafür ist ggf.
> nicht genug Speicher.

Falls BASE eine Schnittstellenklasse ist geht das eh, da ja BASE dann 
abstrakt ist. Ansonsten geht es schon, allerdings mit Object-Slicing. 
Dann kann erwünscht sein, meistens ist es das nicht.

von Wilhelm M. (wimalopaan)


Lesenswert?

abc schrieb:
> Was du vllt meinst ist ein normales Array? Das hat natürlich keine
> iteratoren.

Jeder Container mit zusammenhängender Speicherung hat Iteratoren, in 
diesem Fall Zeiger: jeder Zeiger ist ein Iterator, aber nicht jeder 
Iterator ist ein Zeiger. S.a. Beispiel mit der Liste.

Insofern haben auch rohe C-Array Iteratoren, nämlich Zeiger. 
std::begin()/std:end() sind dafür entsprechend spezialisiert.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Falls BASE eine Schnittstellenklasse ist geht das eh, da ja BASE dann
> abstrakt ist.

Schnittstellenklassen gibt es in C++ nicht. Wenn "BASE" eine abstrakte 
Klasse ist, also eine rein virtuelle Funktion hat wie hier "Draw", geht 
es eben auch nicht, weil man keine Instanzen davon anlegen kann, und 
"std::list<BASE>" aber eben nur Instanzen von BASE enthalten kann und 
nichts anderes. Hier zu sehen:

https://godbolt.org/z/3snhqf5Ko

Wilhelm M. schrieb:
> Ansonsten geht es schon, allerdings mit Object-Slicing.

Aber nicht mit abstrakten Klassen.

von Wilhelm M. (wimalopaan)


Lesenswert?

std::array oder std::vector haben spezielle Iteratoren, in diesem Fall 
RandomAccessIterator, die werden für das Sortieren benötigt. Die 
einfachsten Iteratoren sind InputIteratoren oder auf Forward-Iteratoren.

von Wilhelm M. (wimalopaan)


Lesenswert?

Niklas G. schrieb:
> Schnittstellenklassen gibt es in C++ nicht.

Selbstverständlich gibt es die! Das sind abstrakte Klassen nur 
rein-virtuellen Elementfunktionen (und natürlich virtuellem DTor).

Niklas G. schrieb:
> Wilhelm M. schrieb:
>> Ansonsten geht es schon, allerdings mit Object-Slicing.
>
> Aber nicht mit abstrakten Klassen.

Das habe ich für selbstverständlich gehalten ...

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Selbstverständlich gibt es die! Das sind abstrakte Klassen nur
> rein-virtuellen Elementfunktionen (und natürlich virtuellem DTor).

Spannend, wo ist das im C++-Standard definiert?

Wilhelm M. schrieb:
> Das habe ich für selbstverständlich gehalten ...

Klang nicht so, wenn du vorher behauptest dass es mit abstrakten Klassen 
welche auch "Schnittstellenklassen" sind doch geht.

von Wilhelm M. (wimalopaan)


Lesenswert?

Niklas G. schrieb:
> Spannend, wo ist das im C++-Standard definiert?

Dort nicht. Warum sollte es dort auch drin stehen?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Dort nicht. Warum sollte es dort auch drin stehen?

Alles was es in C++ gibt, ist im C++-Standard definiert. Was nicht im 
C++-Standard steht, ist nicht C++, sondern eine Erweiterung oder eigene 
Definition. Somit gibt es in C++ selbst keine Schnittstellenklassen, man 
kann sich das höchstens selbst so definieren. Wenn sich aber jeder 
selbst solche Definitionen bastelt kann es schnell zu 
Abstimmungsproblemen kommen.

von Pantoffel (Gast)


Lesenswert?

Random .. schrieb:
> Bei std::map natürlich zuerst auf dem map-objekt operieren:
>
1
> for(auto item : items) {
2
>   TYPEf first = item.first;
3
>   TYPEs second = item.second;
4
> }
5
>

Oder mit structured binding:
1
for(auto& [first, second] : items) {
2
  // ...
3
}

von Wilhelm M. (wimalopaan)


Lesenswert?

Niklas G. schrieb:
> Wilhelm M. schrieb:
>> Dort nicht. Warum sollte es dort auch drin stehen?
>
> Alles was es in C++ gibt, ist im C++-Standard definiert. Was nicht im
> C++-Standard steht, ist nicht C++, sondern eine Erweiterung oder eigene
> Definition. Somit gibt es in C++ selbst keine Schnittstellenklassen, man
> kann sich das höchstens selbst so definieren. Wenn sich aber jeder
> selbst solche Definitionen bastelt kann es schnell zu
> Abstimmungsproblemen kommen.

Nur weil es das in anderen, weniger allgemeinen Sprachen wie Java 
explizit gibt, muss es das in C++ nicht genauso im Sprachstandard geben.

Schnittstellenvererbung und Liskov sind eine Säule der OOP. Nun ist C++ 
im Gegensatz etwa zu Java eine Multiparadigmensprache. So unterstützt 
sie eben auch z.B. Implementierungsvererbung. Und etwa statische 
Polymorphie, und diesen Begriff findest Du so auch nicht im C++ 
Standard.

Also: Schnittstelle ist ein Konzept, dazu braucht es in der Sprache 
keine 1:1 Umsetzung zu geben, lediglich muss die Sprache unterstützen. 
Und das tut C++.

: Bearbeitet durch User
von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Also: Schnittstelle ist ein Konzept, dazu braucht es in der Sprache
> keine 1:1 Umsetzung zu geben, lediglich muss die Sprache unterstützen.
> Und das tut C++.

Ich finde es gefährlich, in einer Antwort auf eine Anfänger-Frage 
Konzepte zu erwähnen, die nicht Teil der Sprache sind, und mit fest 
definierten Sprachelementen (abstrakte Klasse) zu mischen - und zu 
behaupten, sie seien Teil von C++, obwohl eben nicht im Sprachstandard 
definiert. Das sollte man wenn schon genau unterscheiden. Zumal es an 
der Stelle und bei C++ allgemein sowieso keinen Unterschied macht ob 
alle oder einige Funktionen rein-virtuell sind.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Niklas G. schrieb:
> Ich finde es gefährlich, in einer Antwort auf eine Anfänger-Frage
> Konzepte zu erwähnen, die nicht Teil der Sprache sind, und mit fest
> definierten Sprachelementen (abstrakte Klasse) zu mischen.

Dem Anfänger habe ich gar nicht geantwortet, ich habe Dir geantwortet. 
Und ich wiederum finde es gefährlich, zu behaupten, eine 
OOP-unterstützende Sprache besäße keine Schnittstellenklassen. Das ist 
schlicht falsch.

von Wilhelm M. (wimalopaan)


Lesenswert?

Niklas G. schrieb:
> Zumal es an
> der Stelle und bei C++ allgemein sowieso keinen Unterschied macht ob
> alle oder einige Funktionen rein-virtuell sind.

Bezogen, ob man das nun als Schnittstelle bezeichnet, schon. Vgl. es 
einfach mal mit dem interface in Java.

Jeder, der sich mit OOP beschäftigt, sollte das Schnittstellenkonzept 
verstanden haben, egal ob es dafür nun ein Schlüsselwort gibt oder 
nicht. Das ist vollkommen irrelevant.

: Bearbeitet durch User
von Klaus W. (mfgkw)


Lesenswert?

Es gibt abstrakte Schnittstellen natürlich schon in C++, die heißen dann 
halt nur nicht so (sondern gelegentlich ABC = abstract base class).

Man muß sie auch nicht explizit erwähnen in irgendeinem Standard, weil 
sie wie jede andere Klasse auch sind, nur daß man alles weglässt außer 
pure virtual Funktionen.
Dementsprechend kann man dann keine Objekte keine davon instantiieren, 
und folglich auch nicht in einem Container verwalten.

Insofern verstehe ich nicht, warum hier darum gestritten wird - hat mit 
dem Thema doch überhaupt nichts zu tun.

(Daß es Schnittstellen, die keine Klassen sind, bspw. in Java überhaupt 
gibt, liegt nur daran daß Java keine Mehrfachvererbung kennt. 
Ersatzweise kann man nur von einer einzigen echten Klasse ableiten und 
muß den Rest über leere Schnittstellen machen, wo C++ stattdessen von 
mehreren Basisklassen erben kann - in denen etwas stehen kann, aber 
nicht muß.
So kann man einen Mangel in Java als Feature deklarieren: C++ hat ja 
nicht mal Schnittstellen...)

von Wilhelm M. (wimalopaan)


Lesenswert?

Klaus W. schrieb:

> Insofern verstehe ich nicht, warum hier darum gestritten wird - hat mit
> dem Thema doch überhaupt nichts zu tun.
>
> (Daß es Schnittstellen, die keine Klassen sind, bspw. in Java überhaupt
> gibt, liegt nur daran daß Java keine Mehrfachvererbung kennt.
> Ersatzweise kann man nur von einer einzigen echten Klasse ableiten und
> muß den Rest über leere Schnittstellen machen, wo C++ stattdessen von
> mehreren Basisklassen erben kann - in denen etwas stehen kann, aber
> nicht muß.
> So kann man einen Mangel in Java als Feature deklarieren: C++ hat ja
> nicht mal Schnittstellen...)

Genau das sage ich doch. Ich weiß auch nicht, warum man das in Zweifel 
zieht. Das sind doch wirklich Basics.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Dem Anfänger habe ich gar nicht geantwortet, ich habe Dir geantwortet.

Stimmt, aber falsch war es trotzdem - wenn "BASE" abstrakt ist, kann man 
es nicht sinnvoll in "std::list<BASE>" nutzen, egal ob es jetzt eine 
"Schnittstellenklasse" ist oder nicht. Der Satz

> Falls BASE eine Schnittstellenklasse ist geht das eh, da ja BASE dann abstrakt 
ist.

ist also falsch und sinnlos, weil es sowieso nicht davon abhängig ist, 
ob alle oder einige Funktionen rein-virtuell sind.

Wilhelm M. schrieb:
> Und ich wiederum finde es gefährlich, zu behaupten, eine
> OOP-unterstützende Sprache besäße keine Schnittstellenklassen. Das ist
> schlicht falsch.

Man kann sich so etwas ähnliches wie eine Schnittstellenklasse bauen. 
Aber das ist nicht im Standard definiert und hat kein spezielles 
Verhalten oder Unterstützung seitens der Sprache.

Wilhelm M. schrieb:
> Vgl. es
> einfach mal mit dem interface in Java.

Ganz genau - Schnittstellenklassen in Java werden gesondert behandelt 
mit speziellen Eigenschaften, in C++ nicht - man kann also durchaus 
sagen, dass Java Schnittstellenklassen hat, und C++ nicht.

von Wilhelm M. (wimalopaan)


Lesenswert?

Niklas G. schrieb:
> Man kann sich so etwas ähnliches wie eine Schnittstellenklasse bauen.
> Aber das ist nicht im Standard definiert und hat kein spezielles
> Verhalten oder Unterstützung seitens der Sprache.

Das ist doch jetzt wirklich falsch.
Im Standard findest Du auch nicht den Begriff Meta-Funktion: und es gibt 
sich doch. Genauso wie reine Funktionen oder allg. Funktionen. Nur weil 
es Schlüsselwort nicht vorkommt, heißt es nicht, das es das Konzept 
nicht gibt.

Mit Deiner Wortklauberei verwirrst Du doch jetzt hier jeden Anfänger.

von Wilhelm M. (wimalopaan)


Lesenswert?

Niklas G. schrieb:
>> Falls BASE eine Schnittstellenklasse ist geht das eh, da ja BASE dann abstrakt
> ist.

Ja, das war in der Tat falsch von mir: ich hatte den * einfach 
hinzugedacht ;-)

von mh (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Mit Deiner Wortklauberei verwirrst Du doch jetzt hier jeden Anfänger.
Also ich muss sagen, Niklas ist deutlich klarer in seinen 
Formulierungen.

Dein Beitrag
Wilhelm M. schrieb:
> Niklas G. schrieb:
>> Das funktioniert nicht. So kann man nur Objekte der Klasse "BASE" in
>> die Liste einfügen, aber nicht die abgeleiteten, denn dafür ist ggf.
>> nicht genug Speicher.
>
> Falls BASE eine Schnittstellenklasse ist geht das eh, da ja BASE dann
> abstrakt ist. Ansonsten geht es schon, allerdings mit Object-Slicing.
> Dann kann erwünscht sein, meistens ist es das nicht.
Hat mich erstmal ziemlich verwirrt. Ich habe mich ne ganze Weile 
gefragt, was diese Schnittstellenklasse sein soll, die abstrakt und in 
einem std::vector gespeichert werden kann. Hättest du nicht unnötig das 
Wort Schnittstellenkklasse benutzt, Wäre sofort offensichtlich gewesen, 
dass du die Verneinung in dem Satz vergessen hast.

von Wilhelm M. (wimalopaan)


Lesenswert?

mh schrieb:
> Also ich muss sagen, Niklas ist deutlich klarer in seinen
> Formulierungen.

Ich habe Schnittstellenklasse gesagt, damit war ganz kurz alles klar. 
Dann fing er an zu behaupten, so etwas gäbe es in C++ nicht. Also ich 
denke, es mit einem Wort wie Schnittstellenklasse oder ein Schnittstelle 
zu sagen, ist ziemlich klar und kurz.

von Wilhelm M. (wimalopaan)


Lesenswert?

Random .. schrieb:
> Stimmt, zugegeben, dieses Detail hatte ich vergessen. Hat sich doch ein
> Fehler eingeschlichen :-)

Auch das geht: std::variant<> als Elementtyp ist der Schlüssel zum 
Erfolg.
Oh: ich hätte auch diskriminierender Summentyp sagen können, aber sowas 
gibt es in C++ nicht, oder doch ;-)

: Bearbeitet durch User
von Klaus W. (mfgkw)


Lesenswert?

Wilhelm M. schrieb:
> Auch das geht: std::variant<> als Elementtyp ist der Schlüssel zum
> Erfolg.

Nachdem die Diskussion zum ursprünglichen Thema inzwischen eh vergeigt 
ist, schlage ich void* vor ... :-)

von mh (Gast)


Lesenswert?

Wilhelm M. schrieb:
> mh schrieb:
>> Also ich muss sagen, Niklas ist deutlich klarer in seinen
>> Formulierungen.
>
> Ich habe Schnittstellenklasse gesagt, damit war ganz kurz alles klar.
> Dann fing er an zu behaupten, so etwas gäbe es in C++ nicht. Also ich
> denke, es mit einem Wort wie Schnittstellenklasse oder ein Schnittstelle
> zu sagen, ist ziemlich klar und kurz.

Das kannst du gerne behaupten. Meine Erklärung hast du ja 
praktischerweise ignoriert.

von Wilhelm M. (wimalopaan)


Lesenswert?

Klaus W. schrieb:
> Nachdem die Diskussion zum ursprünglichen Thema inzwischen eh vergeigt
> ist, schlage ich void* vor ... :-)

Damit es dann auch richtig schief geht: union

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Niklas G. schrieb:
>> Das funktioniert nicht. So kann man nur Objekte der Klasse "BASE" in
>> die Liste einfügen, aber nicht die abgeleiteten, denn dafür ist ggf.
>> nicht genug Speicher.
>
> Falls BASE eine Schnittstellenklasse ist geht das eh, da ja BASE dann
> abstrakt ist. Ansonsten geht es schon, allerdings mit Object-Slicing.
> Dann kann erwünscht sein, meistens ist es das nicht.

Mir würde nichts einfallen, wo man Slicing bewusst haben will. Und die 
gewünschte Polymorphie ist damit auch weg.

Wilhelm M. schrieb:
> Also: Schnittstelle ist ein Konzept, dazu braucht es in der Sprache
> keine 1:1 Umsetzung zu geben, lediglich muss die Sprache unterstützen.
> Und das tut C++.

Es gibt ziemlich viele Konzepte, die man in C++ umsetzen kann. Deshalb 
würde nicht nicht sagen, dass die alle Teil von C++ sind.

von Experte (Gast)


Lesenswert?

helpme91 schrieb:
> Ich Frage, da ich einen Beitrag gelesen habe wo gesagt wurde, das man
> bei vector Listen grundsätzlich ohne Iterator arbeitet.

Verallgemeinerungen sind grundsätzlich falsch.

von Klaus W. (mfgkw)


Lesenswert?

Experte schrieb:
> Verallgemeinerungen sind grundsätzlich falsch.

So wie diese.

von Rolf M. (rmagnus)


Lesenswert?

Klaus W. schrieb:
> Experte schrieb:
>> Verallgemeinerungen sind grundsätzlich falsch.
>
> So wie diese.

Gratulation, du hast die Ironie dieses Satzes erkannt.

von Klaus W. (mfgkw)


Lesenswert?

tja, sicher ist sicher.

von Sebastian (Gast)


Lesenswert?

Geht wirklich ohne Iterator ("um mit
der Liste was machen zu können"): pop_front, pop_back, front, back, ...

von Rolf M. (rmagnus)


Lesenswert?

Dann braucht man aber auch keine verkettete Liste mehr. Da tut's auch je 
nach Anwendung ein stack, eine queue oder eine deque.

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.