Контейнер C ++ полиморфных объектов с общим VPTRC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Контейнер C ++ полиморфных объектов с общим VPTR

Сообщение Anonymous »

Предположим, что мне нужно хранить коллекцию объектов того же типа , но этот тип нельзя определить во время компиляции. Предположим, что после определения этого типа он никогда не меняется. Также хорошо известно, когда тип не известен во время компиляции, можно сохранить эти объекты, используя контейнер с указателями на их базовый класс, то есть < /p>

Код: Выделить всё

std::vector collection;
collection.push_back( new Derived() );
< /code>

Таким образом, выделенные объекты не обязательно будут сохранены рядом в памяти, потому что в каждом распределении New () < /code> будет возвращать произвольную позицию в памяти. Кроме того, есть дополнительный указатель (vptr
) embedded to each object, because the Base class of course needs to be polymorphic.

For this particular case (type is defined once + type never changes), the above solution is not the optimal solution, because, theoretically,
  • it's not necessary to store the same vptr (sizeof () = размер указателя) для каждого объекта: все они указывают на одни и те же vtable ;
  • Можно использовать смежные места хранения, поскольку размер объектов определяется в начале программы и никогда не изменится.
Allocator/Idiom/Trick/Что -нибудь еще, чтобы преодолеть эти проблемы?struct Triangle_Data {
double p1[3],p2[3],p3[3];
};

struct Circle_Data {
double radius;
};

struct Shape {
virtual double area() const = 0;
virtual char* getData() = 0;
virtual ~Shape() {}
};

struct Triangle : public Shape {
union {
Triangle_Data tri_data;
char data[sizeof(Triangle_Data)];
};
double area() const { /*...*/ };
char* getData() { return data; }
Triangle(char * dat_) {
std::copy(dat_, dat_+sizeof(Triangle_Data), this->data);
};
};

struct Circle : public Shape {
union {
Circle_Data circ_data;
char data[sizeof(Circle_Data)];
};
double area() const { /*...*/ };
char* getData() { return data; }
Circle(char * dat_) {
std::copy(dat_, dat_+sizeof(Circle_Data), this->data);
};
};

template
struct Container {
int n_objects;
int sizeof_obj;
std::vector data;
Container(...arguments here...) : ...init here... {
data.resize( sizeof_obj * n_objects );
}
void push_back(Shape* obj) {
// copy the content of obj
for( int i=0; i

Подробнее здесь: https://stackoverflow.com/questions/158 ... hared-vptr
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»