seltsames template-problem
-
Hallo
template<class T> struct Data { T *ptr; unsigned count; }; template<class T> struct DataN : public Data<T> { DataN(T *t) { ptr = t; count = 1; } ~DataN() {delete ptr;} };warum schluckt das der msvc++ aber der c::b nicht? der code ist doch richtig??
-
der code ist doch richtig??
glaube ich nicht...
~DataN() {delete ptr;}ptr ist hier schon nicht mehr da, da die untergeordneten objekte bereits zerstört sind...
die lösung ist aber ganz einfach - man gibt dem struct Data nen CTor und nen DTor - dann gehts nich nur, dann ists auch logisch

also so in etwa:
template<class T> struct Data { //evtl op= und copy-ctor verbieten?! T *ptr; unsigned count; Data (T* _ptr) : ptr(_ptr), count(1) {} Data () : ptr(nullptr), count(0) {} ~Data () { delete ptr; } //evtl noch auf count testen - weiß jz nicht genau, was Data sein soll und was count zählen soll - vll willste ja ne art shared_ptr nachbauen... }; template<class T> struct DataN : public Data<T> { DataN(T *t) : Data (t) {} };bb
-
@unskilled,
Der Lösungsvorschlag ist zwar eine gute Idee, aber deine Begründung stimmt nicht. Auchptrist noch vorhanden, wenn der Destruktor aufgerufen wird. Der Fehler liegt hier woanders.@template<class user>,
1. C::B ist kein Kompiler, sondern nur eine IDE. Aber ich nehme mal an, dass du den GCC verwendet hast.
2. Deine Fehlerbeschreibung ist etwas sehr dürftig.
3. Der Code ist laut Standard falsch, der MSVC ist mit dem Programmierer, wie so oft, etwas nachsichtiger.Problem ist hier:
Wenn die Basisklasse eine Template abhängige Klasse ist, dann wird der Scope dieser Klasse nicht herangezogen, um die unqualifizierten Namen aufzulösen. Ein kurzes Beispiel:#include <iostream> template<typename T> struct Base { int i; }; int i; template<typename T> struct Derived : public Base<T> { Derived(int x) { i = x; } }; int main() { ::i = 25; Derived<int> d(10); std::cout << ::i << std::endl; return 0; }Die Ausgabe, auf einem Standard konformen Kompiler, ist hier 10. Obwohl man eigentlich eher 25 erwarten würde

Dein Code wäre so korrekt:
template<class T> struct Data { T *ptr; unsigned count; }; template<class T> struct DataN : public Data<T> { DataN(T *t) { Data<T>::ptr = t; Data<T>::count = 1; } ~DataN() {delete Data<T>::ptr;} };Du musst also den Scope explizit angeben.
Grüssli
-
hmm... stimmt - das hatte nur was mit vtables zu tun, was ich meinte ^^
-
Anmerk: Das public beim Ableiten kannst du dir sparen! :p
-
David_pb schrieb:
Anmerk: Das public beim Ableiten kannst du dir sparen! :p
Hatte es am Anfang nicht drin, bei meinem Beispiel, war mir dann aber doch nicht mehr sicher, ob dem so war. Hab es grad schnell noch im Standard nachgeschaut. Jap, structs sind nicht nur default public bei den Membern, sondern auch default public bei der Ableitung. Naja, aber lieber das ganze einheitlich halten.

Falls es wen interessiert, entscheidend dabei ist, von welchem "Klassentyp" (struct / class) die abgeleitete Klasse ist.Grüssli
-
hm, erstmal danke an euch, insbesondere an Dravere
komme halt von msvc her
wieder was gelernt
das die basisklasse kein dtor hat ist schon richtig
-
unskilled schrieb:
hmm... stimmt - das hatte nur was mit vtables zu tun, was ich meinte ^^
Nein.
Du hast schlicht und ergreifend die Basisklasse mit der Abgeleiteten verwechselt.
-
hustbaer schrieb:
unskilled schrieb:
hmm... stimmt - das hatte nur was mit vtables zu tun, was ich meinte ^^
Nein.
Du hast schlicht und ergreifend die Basisklasse mit der Abgeleiteten verwechselt.oder das.... ^^
naja - war bissl mehr, als nur das verwechselt - aus irgend nem grund hatte ich sofort an so was gedacht:struct a { virtual void foo() = 0; ~a() {foo();} }; struct b : a { void foo() {std::cout << 2;} }; int main() { b bar; }naja - wären scho wieder beinahe 20 fehler drin gewesen... ich geh jz besser ma ins bett ^^
gn8 xD
-
unskilled schrieb:
naja - wären scho wieder beinahe 20 fehler drin gewesen... ich geh jz besser ma ins bett ^^
Make it so
