BigThree Problem
-
Gehört TGGC eigentlich auch zu den Big Three?
-
naaa schrieb:
Gehört TGGC eigentlich auch zu den Big Three?
Nein, dafür ist er zu schlecht.
-
ich denke mal HumeSikkins und volkard gehören auf jeden Fall dazu. Aber wer noch?

-
och leute....
-
Ok, also wenn du weisst dass du nur abgeleitete klassen verwalten musst dann brauchst du keine templates. Du arbeitest eben mit den basisklassenzeigern.
Dass man keine instanz einer abstracten klass erzeugen kann liegt in der natur der c++-dinge, da wirst du nichts dran drehen können. Was du willst ist offensichtlich eine deep-copy-semantic beim op= und copy-ctor. Gut dann musst
du aber dafür sorgen dass du nie mit null-pointern zu tun hast. Weil sonst immer das problem mit der instanzierung der basis auftritt. Der container ist nicht für allocierung bzw. deallocierung verantwortlich. Wenn der container leer ist enthält er kein objekt, wenn er die größe 1 hat dann enthält er eben ein definiertes objekt. Es ist aufgabe des clients dafür zu sorgen dass da ordentliche werte vorhanden sind um damit arbeiten zu können wie ers erwartet.Kannst du mal sagen warum du diesen weg überhaupt gehst mit dem eigenen container ? Ich meine einen groben umriss des kontexts geben, dass man mal schaun kann ob das nicht auch anders geht ?
Ich würde wahrscheinlich boost::array <basis*> verwenden. Aber es kann ja sein dass das für dich nich ausreicht weil du noch irgendwas besonderes machen willst. Aber vom jetzigen standpunkt aus verschliesst sich mir irgendwie der sinn des ganzen.
Ansonsten kannst du auch einfach ne shallow-copy der zeiger machen, musst halt nur drauf achten dass die zeiger nicht ausversehen durch einen andren container zerstört werden. Deswegen sollte der container auch die elemente nicht im dtor oder ähnliches freigeben. Dafür ist auch der client verantwortlich.
Sry nochmal, das muss frustrierend für dich sein aber probiers doch nochmal genau zu schildern bitte.
-
big three schrieb:
ich denke mal HumeSikkins und volkard gehören auf jeden Fall dazu. Aber wer noch?

TGGC

-
Ok, also wenn du weisst dass du nur abgeleitete klassen verwalten musst dann brauchst du keine templates. Du arbeitest eben mit den basisklassenzeigern.
Gut, dann werde ich meine Klasse ungenerisch machen.
Dass man keine instanz einer abstracten klass erzeugen kann liegt in der natur der c++-dinge, da wirst du nichts dran drehen können. Was du willst ist offensichtlich eine deep-copy-semantic beim op= und copy-ctor.
Ja

Gut dann musst
du aber dafür sorgen dass du nie mit null-pointern zu tun hast. Weil sonst immer das problem mit der instanzierung der basis auftrittIch brauchte halt einen Wert, der mir signalisiert, dass in einem Feld kein ABC Objekt vorhanden ist. Der NULL Pointer bot sich IMHO dafuer an.
Der container ist nicht für allocierung bzw. deallocierung verantwortlich.
Wie jetzt? Wer dann? Ich wuesste nicht, wie ich beim CopyCtor um eine Allokation herumkommen koennte.
Kannst du mal sagen warum du diesen weg überhaupt gehst mit dem eigenen container ? Ich meine einen groben umriss des kontexts geben, dass man mal schaun kann ob das nicht auch anders geht ?
Ich brauchte einige spezielle member functions, die kein std container bereitstellt. Meine Container Klasse ist auch nur ganz kurz und eigentlich
recht simpel.Es geht mir im Moment nicht so sehr darum, dass ich ja viel einfacher eine bereits fertige Containerklasse verwenden koennte.
Das eigentliche Problem liegt darin: Ich habe eine Klasse, die ein Attribut vom Typ Zeiger auf ABC hat. Ich habe mich jetzt gefragt, wie ich den CopyCtor und den AssignmentOp zu implementieren habe, um das Attribut zu kopieren, ohne seinen genauen Typ zu wissen(weil ich ja 12 Unterklassen habe) und dabei noch die NULL Pointer angemessen behandeln zu koennen.
std::vector etc koennen das doch auch!
Wie machen die das denn?
Mir kommt das Problemm so alltaeglich vor!
-
Hi,
wenn ich micht nicht irre passiert bei vectoren von zeigern auch keine tiefe copie. AFAIK werden da nur zeiger kopiert. Deswegen kann der das. Aber das ist ja nicht was du willst. Weil eine veränderung eines elements im einen container eine änderung desselben elements im andren container nach sich ziehen würde.
Ich hab allerdings jetzt auch nicht nachgesehen, also wenn das nicht stimmen sollte möge man mich korrigieren.
Aber eins scheint mir sicher, du kannst keine instanz der basis erzeugen um dann evtl. danach die ableitete klasse tief reinzukopieren. Das musst du irgendwie umgehen.
Man könnte ja zum beispiel sowas überlegen.
class base{ public: explicit base(const bool c=false):concrete_(c){} virtual ~base(){} virtual void func()=0; void concrete(const bool &n){concrete_=n;} const bool &concrete() const {return conctrete_;} private: bool concrete_; }; class derived : public base{ public: derived(const int v,const int v2) : base(true),v1_(v),v2_(v2) {} void func(){} private: int v1_; int v2_; };Dann könntest du mit zeigern und tiefen copien in deinem container arbeiten. Und wenn du die werte brauchst müsstest du vorher testen ob concrete true ist oder nicht und entsprechend im einen fall von unsinn ausgehen und im andren von sinnvollen werten.
-
An einen capability query hatte ich auch schon gedacht. Koennte ich mal probieren.
Falls die Standard Container alle nur triviale CopyCtors und AssignmentOps haben, dann wundert mich gar nichts mehr. Dann ist das ja kein Problem

Ich haette aber nicht gedacht, dass mein Problem doch so subtil ist.Ich werde da noch n bisschen rumgruebeln...
Dank dir vielmals fuer deine Muehe! thx.@all: so, jetzt koennt ihr weiter ausdiskutieren, wer der dritte unter den BigThree ist

-
und deinen clients einen virtuellen konstruktor aufzwingen willst du auch nicht?
-
Werner Salomon ist der Dritte!

-
Ich hab gerade mal nachgesehen.
copy-ctor meiner vector-implementierung:
/** * @brief %Vector copy constructor. * @param x A %vector of identical element and allocator types. * * The newly-created %vector uses a copy of the allocation * object used by @a x. All the elements of @a x are copied, * but any extra memory in * @a x (for fast expansion) will not be copied. */ vector(const vector& __x) : _Base(__x.size(), __x.get_allocator()) { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }Da werden so wie ich das sehe auch nur zeiger kopiert.
uninitialized_copy würde in deinem fall so aussehen, da du ja mit zeigern also POD-typen arbeitest.
template<typename _InputIter, typename _ForwardIter> inline _ForwardIter __uninitialized_copy_aux(_InputIter __first, _InputIter __last, _ForwardIter __result, __true_type) { return copy(__first, __last, __result); } template<typename _InputIter, typename _ForwardIter> inline _ForwardIter uninitialized_copy(_InputIter __first, _InputIter __last, _ForwardIter __result) { typedef typename iterator_traits<_ForwardIter>::value_type _ValueType; typedef typename __type_traits<_ValueType>::is_POD_type _Is_POD; return __uninitialized_copy_aux(__first, __last, __result, _Is_POD()); }Es gibt da noch spezialisierungen für char pointer.
Und im dtor steht auch was ich schon sagte.
/** * The dtor only erases the elements, and note that if the elements * themselves are pointers, the pointed-to memory is not touched in any * way. Managing the pointer is the user's responsibilty. */ ~vector() { _Destroy(_M_start, _M_finish); }@std.proposal
seit wann dürfen denn ctors virtual sein ? oder meinst du das anders ?
-
Ich glaub ich habs! Ein virtueller Ctor wuerde Abhilfe schaffen!
class ABC { public: virtual ABC* clone()=0; }; class Derived { public: virtual ABC* clone() { return new Derived(*this); } };
-
Ups.. erst lesen, dann schreiben.
Anscheinend hatte ich die selbe Idee wie std.proposal. An der Stelle trotzdem nochmal Danke!@prolog:
Wie uns allen bekannt ist, koennen Konstruktoren nicht virtuell sein. Es gibt aber ein einfaches Idiom, mit dem eine solche Funktionalitaet imitiert werden kann. Das sog. virtual Konstruktor Idiom. Den Code siehst du in meinem obigen Post.
-
@prolog: Du koenntest mir aber sagen, was ein POD ist.
Ist das ein primitiver (also nicht-Klassen)-Typ?
-
Hi,
Japp im prinzip native datentypen.
Klassen können auch PODs sein wenn sie ein paar anforderungen erfüllen.