vector<class with private copy-constr/ referenc
(Autor: T h o r ѕ t e n R о g g е n d ο r f, Frage gestellt am Fr, 18. Mai 2001)
Hi,
diesen Artikel habe ich auch in einem News-Brett gepostet, daher
ist er auf Englisch, fuer Hilfe waere ich dankbar!
I have a class with a private copy-constructor (it has a copy
constructor which needs one more arg though). There is no way to
put that into a vector, is there? So I tried to use references to
that class. But vector can neither deal with references, right?
It's a bit complicated. The class I talk about is nested in
another class. The nested class needs a pointer to the outside,
giving me a Java like call back construct. Now I want to have a
vector of that nested type, and to keep the depending code simple
I'd like to use a vector of objects. Second option would be
vector of references. I'd hate to have to use pointers since the
whole stuff is part of the basic hirarchy for dozens of classes
that depend on it ...
Any ideas? Or are vectors actually able to deal with the problem?
I could also provide a copyconstructor. But that would be unsafe.
It should then only be used by vector not by users of the
surrounding class. Again I don't want to make the nested class
private or protected since it being public provides a nicer
interface for initializing the surrounding class.
I also thought about making vector a friend of my nested class.
That would be fine as far as I am concerned (since the actual
vector in the outside class is private), but that's not enough.
Using my compiler (gcc 2.95.2) I have to make some template
function also a friend. Example code:
Trouble is that construct stuff. Is that part of the STL-Standard
or of the implementation of my compiler. Thus will it be
portable? Oh damnit I just found out, that I have to make two
more friends, to make clearing the vector and other stuff work.
The friends for actual code (I am too lazy, to work it out with
the example ...) would be:
Lol, that can't be portable. So, any ideas?
Cheers
Thorsten
diesen Artikel habe ich auch in einem News-Brett gepostet, daher
ist er auf Englisch, fuer Hilfe waere ich dankbar!
I have a class with a private copy-constructor (it has a copy
constructor which needs one more arg though). There is no way to
put that into a vector, is there? So I tried to use references to
that class. But vector can neither deal with references, right?
It's a bit complicated. The class I talk about is nested in
another class. The nested class needs a pointer to the outside,
giving me a Java like call back construct. Now I want to have a
vector of that nested type, and to keep the depending code simple
I'd like to use a vector of objects. Second option would be
vector of references. I'd hate to have to use pointers since the
whole stuff is part of the basic hirarchy for dozens of classes
that depend on it ...
Any ideas? Or are vectors actually able to deal with the problem?
I could also provide a copyconstructor. But that would be unsafe.
It should then only be used by vector not by users of the
surrounding class. Again I don't want to make the nested class
private or protected since it being public provides a nicer
interface for initializing the surrounding class.
I also thought about making vector a friend of my nested class.
That would be fine as far as I am concerned (since the actual
vector in the outside class is private), but that's not enough.
Using my compiler (gcc 2.95.2) I have to make some template
function also a friend. Example code:
#include <vector>
class A
{
private:
A(const A&) {}
public:
A() {}
friend vector<A>; // I could live with this
friend void construct<A, A> (A *, const A &);
// that construct thing might make the code unportable
};
void main()
{
vector<A> va;
// vector<A&> vra; // not possible
va.push_back (A () );
}Trouble is that construct stuff. Is that part of the STL-Standard
or of the implementation of my compiler. Thus will it be
portable? Oh damnit I just found out, that I have to make two
more friends, to make clearing the vector and other stuff work.
The friends for actual code (I am too lazy, to work it out with
the example ...) would be:
friend class Plug::LinkTable::SameIdLinks * __copy<Plug::LinkTable::SameIdLinks*, Plug::LinkTable::SameIdLinks *, ptrdiff_t>(Plug::LinkTable::SameIdLinks *, Plug::LinkTable::SameIdLinks *, Plug::LinkTable::SameIdLinks *, random_access_iterator_tag, ptrdiff_t *); friend class Plug::LinkTable::SameIdLinks * __copy_backward<Plug::LinkTable::SameIdLinks *, Plug::LinkTable::SameIdLinks *, ptrdiff_t>(Plug::LinkTable::SameIdLinks *, Plug::LinkTable::SameIdLinks *, Plug::LinkTable::SameIdLinks *, random_access_iterator_tag, ptrdiff_t *);
Lol, that can't be portable. So, any ideas?
Cheers
Thorsten
Artikelbaum anzeigen
Re: vector<class with private copy-constr/ refe
(Autor: Ѕ t e f а n W і е ѕ е, Antwort nach 21 Min)
Hi Thorsten :)
A b= c;
ist also unmöglich.
So I tried to use references to that class. But vector can
Alles in allem würde ich an deiner Stelle mal über das Design meiner Klasse nachdenken. "friend" macht den objektorientierten Ansatz sowieso kapputt. Ein Copy-Constructor ist eigentlich ein Muss !!!
Viele Grüße
Stefan.
I have a class with a private copy-constructor (it has a copy
constructor which needs one more arg though).
Das ist eine extrem starke Einschränkung der Verwendbarkeit deiner Klasse. Du kannst nur Referenzen und Zeiger auf solche Klassenobjekte bei Funktionsaufrufen übergeben. Und du kannst nie ein neues Klassenobjekt definieren und ihm gleichzeitig einen Wert zuweisen. So was wieconstructor which needs one more arg though).
A b= c;
ist also unmöglich.
There is no way to put that into a vector, is there?
Nein, es gibt keine Möglichkeit. Aus Effizienzgründen arbeitet eigentlich jede vector<>-Implementation mit dem Copy-Construktor. Ansonsten müsste erst der Constructor und dann der Zuweisungsoperator aufgerufen werden.So I tried to use references to that class. But vector can
neither deal with references, right?
Stimmt, auch das geht nicht. Referenzen sind konstante Zeiger, die automatisch derefernziert werden. Wie alle konstanten Objekte in C++, müssen daher auch Referenzen bei ihrer Definition initialisiert werden:A &a= b; //Ist in Ordnung. A &a; //Gibt schreckliche Haue vom Compiler a= b;
I could also provide a copyconstructor. But that would be
unsafe.
Aber nur so geht's! Eine Klasse ohne Copy-Constructor ist recht nutzlos und sollte eigentlich nie designt werden.unsafe.
It should then only be used by vector not by users of the
surrounding class.
Dazu bräuchtest du eine friend-Deklaration für vector<>, so dass du den Copy-Constructor privat machen kannst, vector<> aber dennoch Zugriff darauf hat. Das Problem ist nur, dass du nicht weißt, welche fremde Funktionen vector<> selbst aufruft. Diese müssten theoretisch auch alle Freunde werden, weil sie vermutlich eine Parameterübergabe durchführen müssen und daher den Copy-Constructor aufrufen ...surrounding class.
Alles in allem würde ich an deiner Stelle mal über das Design meiner Klasse nachdenken. "friend" macht den objektorientierten Ansatz sowieso kapputt. Ein Copy-Constructor ist eigentlich ein Muss !!!
Viele Grüße
Stefan.
Re^2: vector<class with private copy-constr/ re
(Autor: Т һ ο r ѕ t е n R ο g g е n d ο r f, Antwort nach 2 h, 15 Min)
Hi,
Gruende. Bei Funktionsaufrufen verwende ich ohnehin
ausschliesslich const referencen - schon aus Effiziensgruenden,
dahaer ist das schonmal kein Problem.
den Zuweisungsoperator ueberladen, aber so oder so, ich will ja
gerade nicht, dass die Klasse einfach so kopiert wird.
reinkommen ...
dass es mit vector nicht geht ist wohl auch eine
Effizienzgeschichte (oder Schlamperei ,->):
Die Verwenden wohl auch irgendwo pointer oder referencs auf die
zu haltenden Objekte im Vector, sonst waere es kein Problem.
in C++ z.B. nicht anders verwirklichen. Ueberhaupt braucht man
oft nested friend die einen Pointer nach aussen haben (wenn man
die Komplexitaet schwieriger Klassen aufloesen oder das Interface
logisch und uebersichtlich gestalten will). Und das ist
ja auch voellig ok, wenn sich die aeussere Klasse ums kopieren
kuemmert (und die dann die inneren sauber mitkopiert).
und wenn Du mein Posting weiter gelesen haettest, wuesstest Du es
auch ;-) Ergibt sich das Problem der Portabilitaet, weshalb ich
diese Moeglichkeit ausschliesse (obwohl ich es erstmal gemacht
habe um weitermachen zu koennen, bis mir eine Loesung einfaellt).
Und wieder Quatsch - und wieder sorry. Gerade weil nested friends
so eine feine Sache sind hat Java - mit Sicherheit die
"objektorientiertere" Sprache - das Problem gleich in der
Sprachsyntax geloest.
Callback-Funktion in C++ mit Standard-Copy-Constructor
implementierst. Das wuerde mir helfen ;-)
Gruss
Thorsten
Das ist eine extrem starke Einschränkung der Verwendbarkeit
deiner Klasse. Du kannst nur Referenzen und Zeiger auf solche
Klassenobjekte bei Funktionsaufrufen übergeben.
Naja, das ist mir schon klar, und dafuer gibt es auch gutedeiner Klasse. Du kannst nur Referenzen und Zeiger auf solche
Klassenobjekte bei Funktionsaufrufen übergeben.
Gruende. Bei Funktionsaufrufen verwende ich ohnehin
ausschliesslich const referencen - schon aus Effiziensgruenden,
dahaer ist das schonmal kein Problem.
Und du kannst
nie ein neues Klassenobjekt definieren und ihm gleichzeitig
einen Wert zuweisen. So was wie
A b= c;
Ist nicht unbedingt Sache des Copyconstructors. Ich kann ja auchnie ein neues Klassenobjekt definieren und ihm gleichzeitig
einen Wert zuweisen. So was wie
A b= c;
den Zuweisungsoperator ueberladen, aber so oder so, ich will ja
gerade nicht, dass die Klasse einfach so kopiert wird.
Nein, es gibt keine Möglichkeit.
Stimmt, hatte ich nicht drueber nachgedacht, muss ja irgendwiereinkommen ...
Stimmt, auch das geht nicht. Referenzen sind konstante
Zeiger, die automatisch derefernziert werden. Wie alle
konstanten Objekte in C++, müssen daher auch Referenzen bei
ihrer Definition initialisiert werden:
Das ist mir wohl auch klar. Folgender Code funktioniert z.B.,Zeiger, die automatisch derefernziert werden. Wie alle
konstanten Objekte in C++, müssen daher auch Referenzen bei
ihrer Definition initialisiert werden:
dass es mit vector nicht geht ist wohl auch eine
Effizienzgeschichte (oder Schlamperei ,->):
#include <iostream>
template <class T> class A {
T t;
public:
T readme() {return t;}
//const T& readme; // geht nicht, weil reference auf reference
A(T t0) : t(t0)/*, readme(t)*/ {}
};
void main() {
int a(0);
A<int&> air(a);
cout << air.readme() << endl; // 0
a++;
cout << air.readme() << endl; // 1
}Die Verwenden wohl auch irgendwo pointer oder referencs auf die
zu haltenden Objekte im Vector, sonst waere es kein Problem.
Aber nur so geht's! Eine Klasse ohne Copy-Constructor ist
recht nutzlos und sollte eigentlich nie designt werden.
Das ist - sorry - totaler Quatsch. Callback-Classes lassen sichrecht nutzlos und sollte eigentlich nie designt werden.
in C++ z.B. nicht anders verwirklichen. Ueberhaupt braucht man
oft nested friend die einen Pointer nach aussen haben (wenn man
die Komplexitaet schwieriger Klassen aufloesen oder das Interface
logisch und uebersichtlich gestalten will). Und das ist
ja auch voellig ok, wenn sich die aeussere Klasse ums kopieren
kuemmert (und die dann die inneren sauber mitkopiert).
Dazu bräuchtest du eine friend-Deklaration für vector<>,
so dass du den Copy-Constructor privat machen kannst,
vector<> aber dennoch Zugriff darauf hat. Das Problem
ist nur, dass du nicht weißt, welche fremde Funktionen
vector<> selbst aufruft.
Doch, das weiss ich, der Compiler ist ja kein Geheimniskraemer,so dass du den Copy-Constructor privat machen kannst,
vector<> aber dennoch Zugriff darauf hat. Das Problem
ist nur, dass du nicht weißt, welche fremde Funktionen
vector<> selbst aufruft.
und wenn Du mein Posting weiter gelesen haettest, wuesstest Du es
auch ;-) Ergibt sich das Problem der Portabilitaet, weshalb ich
diese Moeglichkeit ausschliesse (obwohl ich es erstmal gemacht
habe um weitermachen zu koennen, bis mir eine Loesung einfaellt).
Alles in allem würde ich an deiner Stelle mal über das Design
meiner Klasse nachdenken. "friend" macht den
objektorientierten Ansatz sowieso kapputt.
Gaehn ;->meiner Klasse nachdenken. "friend" macht den
objektorientierten Ansatz sowieso kapputt.
Und wieder Quatsch - und wieder sorry. Gerade weil nested friends
so eine feine Sache sind hat Java - mit Sicherheit die
"objektorientiertere" Sprache - das Problem gleich in der
Sprachsyntax geloest.
Ein Copy-Constructor ist eigentlich ein Muss !!!
Siehe oben. Und sag mir, wie Du nested friends mitCallback-Funktion in C++ mit Standard-Copy-Constructor
implementierst. Das wuerde mir helfen ;-)
Gruss
Thorsten
Re^3: vector<class with private copy-constr/ re
(Autor: Ѕ t е f а n W і е ѕ е, Antwort nach 3 h, 19 Min)
Hi Thorsten :)
Ich kann ja auch :den Zuweisungsoperator ueberladen ...
Doch! Das ist ausschließlich Sache des Copy-Constructors. Der Zuweisungsoperator wird überhaupt nicht aufgerufen!
Hmm. Dann lese mal ein paar Bücher über objektorientiertes Design. C++ ist stark auf den Copy-Constructor ausgerichtet. Das merkst du schon daran, dass du mit Klassen ohne Copy-Constructor die STL nur sehr bedingt nutzen kannst.
Moment, dein Compiler ist kein Geheimniskrämer. Aber du weißt nicht, welche Funktionen andere Compiler aufrufen. Der Standard schreibt ja nicht vor, wie die STL implementiert wird, sondern nur, was sie können muss. Und das hast du ja auch richtig als dein Problem (Portierbarkeit) erkannt :)
Ich hoffe, es ist bei dir kein grundsätzliches Problem, dass du immer sehr müde bist, wenn man dir was Wichtiges sagt :)
cu Stefan.
Und du kannst
nie ein neues Klassenobjekt definieren und ihm gleichzeitig
einen Wert zuweisen. So was wie
A b= c;
Ist nicht unbedingt Sache des Copyconstructors.nie ein neues Klassenobjekt definieren und ihm gleichzeitig
einen Wert zuweisen. So was wie
A b= c;
Ich kann ja auch :den Zuweisungsoperator ueberladen ...
Aber nur so geht's! Eine Klasse ohne Copy-Constructor ist
recht nutzlos und sollte eigentlich nie designt werden.
Das ist - sorry - totaler Quatsch.recht nutzlos und sollte eigentlich nie designt werden.
Dazu bräuchtest du eine friend-Deklaration für vector<>,
so dass du den Copy-Constructor privat machen kannst,
vector<> aber dennoch Zugriff darauf hat. Das Problem
ist nur, dass du nicht weißt, welche fremde Funktionen
vector<> selbst aufruft.
Doch, das weiss ich, der Compiler ist ja kein Geheimniskraemer,so dass du den Copy-Constructor privat machen kannst,
vector<> aber dennoch Zugriff darauf hat. Das Problem
ist nur, dass du nicht weißt, welche fremde Funktionen
vector<> selbst aufruft.
und wenn Du mein Posting weiter gelesen haettest,
Wie kommst du darauf, dass ich das nicht getan habe?
Ergibt sich das Problem der Portabilitaet, weshalb ich
diese Moeglichkeit ausschliesse (obwohl ich es erstmal gemacht
habe um weitermachen zu koennen, bis mir eine Loesung
einfaellt).
s.o.diese Moeglichkeit ausschliesse (obwohl ich es erstmal gemacht
habe um weitermachen zu koennen, bis mir eine Loesung
einfaellt).
Alles in allem würde ich an deiner Stelle mal über das Design
meiner Klasse nachdenken. "friend" macht den
objektorientierten Ansatz sowieso kapputt.
Gaehn ;->meiner Klasse nachdenken. "friend" macht den
objektorientierten Ansatz sowieso kapputt.
Und wieder Quatsch - und wieder sorry. Gerade weil nested
friends
so eine feine Sache sind hat Java - mit Sicherheit die
"objektorientiertere" Sprache - das Problem gleich in der
Sprachsyntax geloest.
Moment! Du kannst bei deinem Problem C++ nicht mit Java vergleichen. C++ ist eine Pseudo-OOP-Sprache, in der du mit gewissen Restriktion leben musst. Eine davon ist z.B., dass jede Klasse einen Copy-Constructor haben sollte. Nicht umsonst gibt es für jede Klasse einen Default-Copy-Constructor, wenn du keinen explizit definiert hast! C++ eignet sich daher auch nur bedingt zum Umsetzen bestimmter OOP-Strukturen.friends
so eine feine Sache sind hat Java - mit Sicherheit die
"objektorientiertere" Sprache - das Problem gleich in der
Sprachsyntax geloest.
... Und sag mir, wie Du nested friends mit
Callback-Funktion in C++ mit Standard-Copy-Constructor
implementierst. Das wuerde mir helfen ;-)
Gar nicht! Dafür ist C++ die falsche Sprache.Callback-Funktion in C++ mit Standard-Copy-Constructor
implementierst. Das wuerde mir helfen ;-)
cu Stefan.
Re^4: vector<class with private copy-constr/ re
(Autor: Τ h о r ѕ t е n R ο g g е n d o r f, Antwort nach 2 Tagen, 8 h, 1 Min)
Hi,
Ich kann ja auch :den Zuweisungsoperator ueberladen ...
Doch!
Oops, gepennt, schon klar.
Weil Du einen Vorschlag gemacht hast, den ich selbst in dem Posting schon gemacht und gleich verworfen habe.
Na, dafuer mache ich das aber ziemlich oft. Aber vielleicht wuerden Dir ja die Haare zu Berge stehen, wenn Du meinen Code saehest ;-)
Ich denke der Vorschlag, der hier noch gekommen ist, ist ganz gut. An was Aehnliches hatte ich auch schon gedacht, aber von vector<> abzuleiten ist eindeutig die Ueberlegene Strategie. Das werde ich mal versuchen.
Gruss
Thorsten
A b= c;
Ist nicht unbedingt Sache des Copyconstructors.Ich kann ja auch :den Zuweisungsoperator ueberladen ...
Hmm. Dann lese mal ein paar Bücher über objektorientiertes
Design.
Ja doch. Wieviele denn noch? ;-)Design.
und wenn Du mein Posting weiter gelesen haettest,
Wie kommst du darauf, dass ich das nicht getan habe?
Moment! Du kannst bei deinem Problem C++ nicht mit Java
vergleichen. C++ ist eine Pseudo-OOP-Sprache, in der du mit
gewissen Restriktion leben musst.
Nein, das ist nun wirklich falsch (dass ich mit Restriktionen leben muss). C++ ist wie C und Java eine allgemeine Programmiersprache mit der sich eine Turingmachiene Programmieren laesst. Der erste C++-"Compiler" hat den C++ Code in C uebersetzt und das Ergebnis dann kompiliert. Man kann damit alles machen. Evtl. laesst sich allerdings nicht vermeiden, dass die Interfaces (und das Design allgemein) darunter leiden. Und im Zweifelsfasll rechtfertigt der Aufwand das Ergebnis nicht.vergleichen. C++ ist eine Pseudo-OOP-Sprache, in der du mit
gewissen Restriktion leben musst.
Eine davon ist z.B., dass
jede Klasse einen Copy-Constructor haben sollte.
Das ist eine Einschraenkung, die ich in meinen Designs niemals akzeptieren wuerde. Natuerlich brauchen die meisten Klassen, zu der Client-Programmierer Zugriff haben einen Copykonstruktor. Aber im private-Bereich? Wozu gibt es denn ueberhaupt nested classes?jede Klasse einen Copy-Constructor haben sollte.
... Und sag mir, wie Du nested friends mit
Callback-Funktion in C++ mit Standard-Copy-Constructor
implementierst. Das wuerde mir helfen ;-)
Gar nicht! Dafür ist C++ die falsche Sprache.Callback-Funktion in C++ mit Standard-Copy-Constructor
implementierst. Das wuerde mir helfen ;-)
Ich denke der Vorschlag, der hier noch gekommen ist, ist ganz gut. An was Aehnliches hatte ich auch schon gedacht, aber von vector<> abzuleiten ist eindeutig die Ueberlegene Strategie. Das werde ich mal versuchen.
Gruss
Thorsten
Re: vector<class with private copy-constr/ refe
(Autor: В e n, Antwort nach 1 Tag, 7 h, 22 Min)
It's a bit complicated. The class I talk about is nested in
another class. The nested class needs a pointer to the
outside,
giving me a Java like call back construct. Now I want to have
a
vector of that nested type, and to keep the depending code
simple
Hmm... ich habe mich auch einmal ein wenig mit diesem Problem beschaeftigt, weil auch mir der Pointersyntax nicht gefiel. Das einzige was mir dazu einfaellt ist eine InterfaceKlasse, ich habe das aber noch nicht ausprobiert.another class. The nested class needs a pointer to the
outside,
giving me a Java like call back construct. Now I want to have
a
vector of that nested type, and to keep the depending code
simple
Das waere dann eine Klasse die private von vector erbt. Alle Zugriffsfunktionen muesstest du dann ueberschreiben, aber das scheinen ja, so wie sich das bei dir anhoert nicht so viele zu sein.
In etwa so:
template <class T> vectorIF : private vector<T*>
{
// notwendige konstruktoren muessen angeboten werden, sollten inline sein, und an vector durchreichen
T operator[](int a) { return *vector<T*>::operator[](a) } // ich habe das jetzt nicht getestet, aber theoretisch muesste es funktionieren
push_back(T* a) { vector<T*>::push_back(a); }
// ... alle anderen funktionen die du noch brauchst, vielleicht gibt es so etwas ja auch
// schon im Netz, denn eigentlich wuerde das ja Sinn machen es einmal fuer den gesamten
// vector durchzuziehen
};
Sag mal Bescheid ob es etwas nuetzt, und wenn ja ob es funktioniert.
Gruss Ben
Re^2: vector<class with private copy-constr/ re
(Autor: S t e f a n W i e ѕ e, Antwort nach 2 Tagen, 18 h, 15 Min)
Hi Ben :)
Bei der von dir vorgeschlagenen Ableitung
Viele Grüße
Stefan.
Bei der von dir vorgeschlagenen Ableitung
template <class T> vectorIF : private vector<T*>
kann es zu Problemen kommen. Man darf nicht einfach so von einer Klasse ableiten, es gibt ein paar Minimalanforderungen, die man an die Mutterklasse richten muss. Die wichtigste ist wohl, dass vector<> einen virtuellen Destructor haben muss. Da du aber nicht weißt, wie vector<> in der STL implementiert ist, machst du vermutlich einen schlimmen Fehler (falls der Destructor nicht virtuell ist) oder/und erzeugst unportablen Code.Viele Grüße
Stefan.
Re^3: vector<class with private copy-constr/ re
(Autor: В е n, Antwort nach 2 Tagen, 23 h, 15 Min)
Hallo Stefan,
Hier wuerde ich widersprechen wollen:
Man benoetigt keinen virtuellen Destruktor wenn man von einer Klasse ableitet. Da hast du wohl etwas ein wenig durcheinander gewuerfelt.
Ein Objekt wird von unten nach oben konstruiert, und in umgekehrter Reihenfolge zerstoert. Das heisst, wenn du von einer Klasse ableitest wird deren Destruktor trotzdem noch aufgerufen. Einen virtuellen Destruktor sollte man dann verwenden, wenn man virtuelle Funktionen verwendet, denn in einem solchen Falle verwendet man statt einer Instanz, oder eines Pointers auf die abgeleitete Klasse haeufig ein Pointer auf die Basisklasse.
Gefaehrlich wird ein nichtvirtueller Destruktor erst, wenn man versucht die Klasse ueber einen Pointer auf eine der Basisklassen zu zerstoeren. Das wuerde dann dazu fuehren, das
die Destruktion mit dem Destruktor der Basisklasse ausgefuehrt wird, und so der Destruktor der abgeleiteten Klasse nicht aufgerufen wird.
Ich bin mir bezueglich meiner Aussage zwar nicht 100%ig sicher, aber so erscheint es mir am logischsten. Auf jeden Fall braucht man im Normalfall bei abgeleiteten Klassen die keine virtuellen Elementfunktionen enthalten keinen virtuellen Destruktor.
Gruss Ben
Hier wuerde ich widersprechen wollen:
Man benoetigt keinen virtuellen Destruktor wenn man von einer Klasse ableitet. Da hast du wohl etwas ein wenig durcheinander gewuerfelt.
Ein Objekt wird von unten nach oben konstruiert, und in umgekehrter Reihenfolge zerstoert. Das heisst, wenn du von einer Klasse ableitest wird deren Destruktor trotzdem noch aufgerufen. Einen virtuellen Destruktor sollte man dann verwenden, wenn man virtuelle Funktionen verwendet, denn in einem solchen Falle verwendet man statt einer Instanz, oder eines Pointers auf die abgeleitete Klasse haeufig ein Pointer auf die Basisklasse.
Gefaehrlich wird ein nichtvirtueller Destruktor erst, wenn man versucht die Klasse ueber einen Pointer auf eine der Basisklassen zu zerstoeren. Das wuerde dann dazu fuehren, das
die Destruktion mit dem Destruktor der Basisklasse ausgefuehrt wird, und so der Destruktor der abgeleiteten Klasse nicht aufgerufen wird.
Ich bin mir bezueglich meiner Aussage zwar nicht 100%ig sicher, aber so erscheint es mir am logischsten. Auf jeden Fall braucht man im Normalfall bei abgeleiteten Klassen die keine virtuellen Elementfunktionen enthalten keinen virtuellen Destruktor.
Gruss Ben
Re^4: vector<class with private copy-constr/ re
(Autor: S t e f а n W і e ѕ e, Antwort nach 3 Tagen, 2 h, 23 Min)
Hi Ben :)
Viele Grüße
Stefan.
Gefaehrlich wird ein nichtvirtueller Destruktor erst, wenn man
versucht die Klasse ueber einen Pointer auf eine der
Basisklassen zu zerstoeren.
Jupp, genau das meine ich! Im C++-Standard steht dazu sehr klar: Wenn Sie versuchen, ein Objekt einer abgeleiteten Klasse durch einen Basisklassen-Zeiger zu löschen und diese Basisklasse keinen virtuellen Konstruktor hat, dann ist das Ergebnis dieser Operation nicht definiert.versucht die Klasse ueber einen Pointer auf eine der
Basisklassen zu zerstoeren.
Ich bin mir bezueglich meiner Aussage zwar nicht 100%ig
sicher, aber so erscheint es mir am logischsten. Auf jeden
Fall braucht man im Normalfall bei abgeleiteten Klassen die
keine virtuellen Elementfunktionen enthalten keinen virtuellen
Destruktor.
Gerade weil man über die STL-Implementierung keine Annahmen machen sollte, ist die Vererbungsmethode daher riskant. Das führt normalerweise zu Fehlern, die man so gut wie nicht finden kann ...sicher, aber so erscheint es mir am logischsten. Auf jeden
Fall braucht man im Normalfall bei abgeleiteten Klassen die
keine virtuellen Elementfunktionen enthalten keinen virtuellen
Destruktor.
Viele Grüße
Stefan.
Re^5: vector<class with private copy-constr/ re
(Autor: В е n, Antwort nach 3 Tagen, 22 h, 29 Min)
Selbst wenn die STL mit virtuellen Funktionen implementiert wird (was aber eher unwahrscheinlich ist, da dies erhoehte Laufzeitkosten zur folge haette) stellt das immer noch kein Problem dar wenn:
a) die abgeleitete Klasse keinen Destruktor benoetigt (was bei einer Interface Klasse im allgemeinen der Fall ist
b) auf die Klasse nicht ueber einen Basispointer zugegriffen wird, was auch nicht sinvoll waere, da sie ja eben nicht als virtuelle Klasse konzipiert ist, allerdings koennte das sinvoll sein, wenn man eine Funktion aufrufen moechte die fuer einen die Basisklasse konzipiert wurde (z.B. deleteVec(vector<T>* pVec {delete pVec;})
Gerade nach Punkt a, aber auch nach Punkt b ist das erstellen einer Interfaceklasse, die von vector erbt aber wahrscheinlich ungefaehrlich (ich glaube Stroustrup macht dies in "Die Programmiersprache C++" auch einmal), obwohl die Container-Klassen nicht als Basis fuer Ableitungen konzipiert wurden.
Gruss Ben
a) die abgeleitete Klasse keinen Destruktor benoetigt (was bei einer Interface Klasse im allgemeinen der Fall ist
b) auf die Klasse nicht ueber einen Basispointer zugegriffen wird, was auch nicht sinvoll waere, da sie ja eben nicht als virtuelle Klasse konzipiert ist, allerdings koennte das sinvoll sein, wenn man eine Funktion aufrufen moechte die fuer einen die Basisklasse konzipiert wurde (z.B. deleteVec(vector<T>* pVec {delete pVec;})
Gerade nach Punkt a, aber auch nach Punkt b ist das erstellen einer Interfaceklasse, die von vector erbt aber wahrscheinlich ungefaehrlich (ich glaube Stroustrup macht dies in "Die Programmiersprache C++" auch einmal), obwohl die Container-Klassen nicht als Basis fuer Ableitungen konzipiert wurden.
Gruss Ben
weitere Artikel aus der Diskussion "vector<class with private copy-constr/ referenc"
- « Zurück
- 1
- 2
- Vorwärts »
Du kannst auf diesen Artikel nicht antworten.
Dieser Artikelbaum ist im Archiv des Experten-Forums von wer-weiss-was zum Thema "C/C++" archiviert. Es handelt sich um keine aktuelle Diskussion, daher kann auf die Artikel nicht mehr geantwortet werden.
Folgende Artikel könnten Dich auch interessieren:
Friend (Englisch)Difference between teachers and educators (engl.)
gesammelte Werke Teil 3 (extrem viel)
gesammelte Werke Teil 4 (extrem viel)
Heavy Boots [ENG]
USA: die Republikaner (sehr lang und Englisch)
Englisch Geschichte
Darwin Awards 2001
FAQ about men
Korrekturlesen (Englisch)
ANTI-GRAVITATIONSMOTOR ! ( info in english )
Amerikanische Logik [ENGL]
vorheriger Artikelbaum
(Menu Maker)
(Registry - wie machen es die 'Großen'? Nur nach Ne)
nächster Artikelbaum















