выстрелил тут себе в ногу.
у меня есть класс который конвертирует говно в специальное концентрированное говно.
class Compressor{
public:
Compressor();
int work(const char *src,char *dst);
private:
int uber_data;
int settings;
char *govnobuf;
};
Compressor *compressors = new Compressor[CPU_COUNT];
ну и они, экземпляры, там запускаются в разных потоках одновременно.
все работает, никаких вопросов.
и тут пришло время прикрутить второй вид концентратора SuperCompressor2.
полиморфизм и отделение интерфейса от реализации спасут нас, решил я и немедленно сделал так:
class AbstractCompressor
{
public:
virtual int work(const char *src,char *dst) = 0;
};
class Compressor: public AbstractCompressor{ ... };
class SuperCompressor2: public AbstractCompressor
{
public:
SuperCompressor2();
int work(const char *src,char *dst);
private:
int settings2;
char *govnobuf;
char *interimbuf;
};
ага.
AbstractCompressor *compressors;
if(application.settings.what_compressor_to_use)
compressor = new Compressor[CPU_COUNT];
else
compressor = new SuperCompressor2[CPU_COUNT];
очень круто. скомпилял, и внутренне радуясь своей сообразительности, запустил.
радость пропала ровно через двадцать секунд, когда программа упала с AV, при вызове
compressor[i].work(src,dst);
расстроился и вернул все обратно. почему? потому что при обращению к массиву компилятор вычисляет смещение исходя из определения оного, то есть получается
(AbstractCompressor *)((char *)compressor + i*sizeof(AbstractCompressor))
ежу понятно, что размеры у базового класса и унаследованного ниразу не обязаны совпадать. а массив, заметьте, выделен как массив дочерних классов. через это у меня случается стресс и депрессия, а у компилятора - говнокод.
спасибо.
1 comment:
Ну чо, с черема не пишется?
Post a Comment