Programım, dinamik başlatma durumunda veri veya nesneleri taşımak için void *' den faydalanmak zorundadır, böylece ilkel olsa bile rasgele türlere ait verileri referans gösterebilir türleri. Ancak, yakın zamanda, çok sayıda temel sınıfları olan sınıflar söz konusu olduğunda bu boşluğu azaltma işleminin başarısız olduğunu ve hatta bellek adresleri doğru gibi görünse bile bu aşağı dökümlü işaretçilerdeki yöntemleri çağırdıktan sonra programımı çökerttiğini keşfettim. Kaza, "vtable" erişim sırasında gerçekleşir.çoklu kalıtım: beklenmedik sonuç void * 'den 2. temel sınıfa dönüldükten sonra
Yani küçük bir test durumu yarattık, çevre Mac OS X üzerinde 4.2 gcc geçerli: Gördüğünüz gibi
Decorated (direct)30,30
Shape 30,30
Square 30,30
Decorated (per void*) 73952,73952
DecoratedSquare 30,30
, "dekore (:
class Shape {
public:
virtual int w() = 0;
virtual int h() = 0;
};
class Square : public Shape {
public:
int l;
int w() {return l;}
int h() {return l;}
};
class Decorated {
public:
int padding;
int w() {return 2*padding;}
int h() {return 2*padding;}
};
class DecoratedSquare : public Square, public Decorated {
public:
int w() {return Square::w() + Decorated::w();}
int h() {return Square::h() + Decorated::h();}
};
#include <iostream>
template <class T> T shape_cast(void *vp) {
// return dynamic_cast<T>(vp); // not possible, no pointer to class type
// return static_cast<T>(vp);
// return T(vp);
// return (T)vp;
return reinterpret_cast<T>(vp);
}
int main(int argc, char *argv[]) {
DecoratedSquare *ds = new DecoratedSquare;
ds->l = 20;
ds->padding = 5;
void *dsvp = ds;
std::cout << "Decorated (direct)" << ds->w() << "," << ds->h() << std::endl;
std::cout << "Shape " << shape_cast<Shape*>(dsvp)->w() << "," << shape_cast<Shape*>(dsvp)->h() << std::endl;
std::cout << "Square " << shape_cast<Square*>(dsvp)->w() << "," << shape_cast<Square*>(dsvp)->h() << std::endl;
std::cout << "Decorated (per void*) " << shape_cast<Decorated*>(dsvp)->w() << "," << shape_cast<Decorated*>(dsvp)->h() << std::endl;
std::cout << "DecoratedSquare " << shape_cast<DecoratedSquare*>(dsvp)->w() << "," << shape_cast<DecoratedSquare*>(dsvp)->h() << std::endl;
}
şu çıktıyı üretir void *) "sonuç tamamen yanlıştır. İlk satırda olduğu gibi 30,30 olmalıdır.
Shape_cast() 'de kullandığım kalıplama yöntemi ne olursa olsun, her zaman Dekorasyon bölümünde kullanılanla aynı beklenmedik sonuçları elde ederim. Bu boşluk ile ilgili bir şey tamamen yanlıştır *.
C++ konusundaki anlayışımdan bu aslında çalışmalıdır. Bunu boşluğa * çalışmak için bir şans var mı? Bu gcc'de bir hata olabilir mi?
sayesinde
Sadece reinterpret_cast öğesini void * 'e çevirmek için ve sonra da orijinal türüne geri döndürebilirsiniz. __NOT__, * ve sonra başka bir şeye çevirme işlemini gerçekleştirebilir. –
Dekoratör kalıbını MI'dan daha iyi kullanabilirsiniz; bu, dökümün void * probleminden çözülmesini sağlamaz. – quamrana