Консультация № 51857
11.08.2006, 14:47
0.00 руб.
0 4 4
Добрый день! У меня вопрос относительно ООП.
Задача:
Создать класс(Model) для хранения, отображения и т.д. модели какой-либо фигуры состоящей из точек(Vertex).

Вопрос заключается в следующем: каким образом можно задать динамический массив для хранения точек? Т.е. можно создать класс и обозначить там заранее массив из 100 вертексов. Но если модель состоит из 5? Тратится память. Если из 120, то ошибка )

Т.е. как можно динамически изменять в классе количество точек?

Класс вертекса

class Vertex
{
public:
float x;
float y;
float z;
}
Класс модели

class Model
{
public:
Vertex Massiv[100];
}

Что нужно изменить?
Заранее спасибо.

Обсуждение

Неизвестный
11.08.2006, 15:05
общий
это ответ
Здравствуйте, PollyRC!

Нужно в классе хранить только указатель на данные. В конструкторе класаа память будет выделяться (под нужное число элементов), в деструкторе - освобождаться. Пример см. в Приложении.

Также можно использовать библиотеку STL:
#include <vector>
...//Пример объявления массива
vector<Vertex> Massiv;
...//Пример добавления данных
Massiv.push_back( Vertex1 );
Massiv.push_back( Vertex2 );
Massiv.push_back( Vertex3 );
...//Пример доступа к данным
Vertex1 = Massiv[1];


Приложение:
class Model{public:Vertex* Massiv;Model(int N){Massiv=new Vertex[N];};~Model(){delete[] Massiv;};}
Неизвестный
11.08.2006, 15:59
общий
это ответ
Здравствуйте, PollyRC!

Настоятельно рекомендую вам изучить станартную библиотеку шаблонов stl.

Она содержит готовые решения для массы таких задач, о которых вы даже не задумавались ^_^ Писать на С++ без шаблонов - всё равно, что ездить на велосипеде, отталкиваяь от земли ногами.

В частности, динамически изменяемый массив из Vertex записывается так:

include <vector>
....

std::vector<Vertex> Massiv;

Massiv.resize(100);

Благодаря перегрузке операторов, работать с таким массивом можно как с обычным

std::cout<<Massiv[5].x;
Вообще, при программировании на С++ рекомендуется избегать С-шного стиля работы с массивами, и пользоваться контейнерами STL, которые более более удобны и зачастую надёжны (дуракоустойчивы).

Благодаря тому, что библиотека шаблонная, её классы имеют минимальные накладные расходы.
Неизвестный
11.08.2006, 21:41
общий
это ответ
Здравствуйте, PollyRC!

Предложу ещё два варианта:

1. Хранить информацию блоками в списке
+ Быстро добавляет элементы (в том числе и в середину)
+ Легко пройти список
+ Легко удалить элемент
+ Хранится по три вертекса сразу (удобно выводить на экран в OpenGL)
- Навигация по списку возможна только вперёд
- Нельзя выбрать конкретный элемент (точнее можно, но долго)
- Сложно сортировать

2. Хранить информацию на предварительно выделеной странице памяти

+ Не даёт модели попасть на стык страниц памяти
+ У программы всегда будет запас памяти на модели
+ Можно дефрагментировать память
+ Можно максимально компактно использовать память
+ Можно подготовить информацию для DX9 достаточно быстро
+ Навигация как в массиве
+ Легко удалить
- Нужно дефрагментировать память
- Выбирается целая страница памяти, если целых нет, то fatal error...
--- Сложно реализовать

Если что-нибудь заинтересует, вышлю реализацию по почте, т.к. громоздко
Неизвестный
12.08.2006, 21:48
общий
это ответ
Здравствуйте, PollyRC!
Для динамического выделения памяти можно использовать несколько способов.
Рассмотрим случай выделения памяти для 100 точек.
1)В объявлении переменных класса вы должны поставить указатель:
class Model
{
public:
Vertex *Massiv;
};

Далее в конструкторе класса используете оператор new или GlobalAlloc:

Massiv = new Vertex[100];
Massiv = (Vertex *)GlobalAlloc(GPTR,sizeof(Vertex)*100);

В деструкторе используете оператор delete или GlobalFree:

delete Massiv;
GlobalFree(Massiv);

2)В начало файла пишете #include <vector>
В объявлении класса:
class Model
{
vector <Vertex> Massiv;
};

В конструкторе:
Massiv.resize(100);

В деструкторе:
Massiv.resize(0);

В таком случае, чтобы определить координату x точки номер 10:
float x = Massiv[10].x;
Форма ответа