class CSensor
{
private:
//**
public:
//**
}
class CSensorsManager
{
private:
CSensor CSensorsCollection[];
public:
CSensorManager(void)
{
CSensor CSensorsCollection[0] = new CSensor;
}
}
Динамический массив объектов в классе
Необходимо создать массив объектов (датчиков) для последущей работы с ними. Делаю следущим образом, а Builder ругается:
Если элементы добавляются/удаляются редко, то можно и через такой массив как у тебя. В этом случае тебе надо сделать метод добавления элемента и метод удаления, в которых ты будешь выделять память под новый массив, копировать в него старые элементы и удалять старый массив.
Можно ещё сделать увеличение размера массива по необходимости не на один элемент, а сразу на несколько (10, 100 или сколько тебе захочется). В этом случае кроме размера массива надо точно знать, сколько сейчас элементов хранится в массиве.
Цитата: Rize
Необходимо создать массив объектов (датчиков) для последущей работы с ними. Делаю следущим образом, а Builder ругается:
Подскажите как корректно создать и инициализировать подобный массив.
Код:
class CSensor
{
private:
//**
public:
//**
}
class CSensorsManager
{
private:
CSensor CSensorsCollection[];
public:
CSensorManager(void)
{
CSensor CSensorsCollection[0] = new CSensor;
}
}
{
private:
//**
public:
//**
}
class CSensorsManager
{
private:
CSensor CSensorsCollection[];
public:
CSensorManager(void)
{
CSensor CSensorsCollection[0] = new CSensor;
}
}
Подскажите как корректно создать и инициализировать подобный массив.
Ругается - это как - он тебя нах посылает? :) Приведи конкретное сообщение об ошибке. Возможно для класса необходимо перегрузить оператор [], или использовать более стандартные решения.
А лучше используй контейнеры.
1. Если кол-во датчиков является постоянным для каждого объекта, то можно использовать простой указатель
Код:
class CSensorsManager
{
private:
CSensor *_fSensors;
int _fSensorsCount;
public:
CSensorManager(int Count)
{
_fSensors = new CSensor [_fSensorsCount = Count];
}
~CSensorManager(void)
{
delete[] _fSensors;
}
}
{
private:
CSensor *_fSensors;
int _fSensorsCount;
public:
CSensorManager(int Count)
{
_fSensors = new CSensor [_fSensorsCount = Count];
}
~CSensorManager(void)
{
delete[] _fSensors;
}
}
Таким образом, для каждого объекта число датчиков будет указано при создании.
Если требуется изменять количество датчиков, то используй контейнеры типа массивов: vector или его аналоги из Borland C++ Builder (DynamicArray).
Если требуется добавлять/удалять датчики из произвольных позиций, то здесь больше подойдут контейнеры типа списков.
Код:
class CSensorsManager
{
private:
class CSensor
{
private:
float CSensorValue;
String CSensorName;
public:
CSensor(void)
{
CSensorValue = 123456;
CSensorName = "!ERROR!";
};
CValStruct CShowSt(void);
};
CSensor* CSensorsCollection[];
CSensor* CTmpColSens[10];
int Count4SenCol;
int Counter;
public:
CSensorManager(void)
{
Count4SenCol = 0;
Counter = 0;
};
void TmpFnc(void)
{
CSensorCollection[Count4SenCol] = new CSensor;
Count4SenCol++;
}
}
{
private:
class CSensor
{
private:
float CSensorValue;
String CSensorName;
public:
CSensor(void)
{
CSensorValue = 123456;
CSensorName = "!ERROR!";
};
CValStruct CShowSt(void);
};
CSensor* CSensorsCollection[];
CSensor* CTmpColSens[10];
int Count4SenCol;
int Counter;
public:
CSensorManager(void)
{
Count4SenCol = 0;
Counter = 0;
};
void TmpFnc(void)
{
CSensorCollection[Count4SenCol] = new CSensor;
Count4SenCol++;
}
}
Функция TmpFnc срабатывает один раз, а на второй проход ломается с ошибкой:
---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00401F28. Write of address 02B42600'. Process stopped. Use Step or Run to continue.
---------------------------
Тогда вопрос почему вылетает не с первого раза?
Теперь, используя следущую конcтрукцию:
Код:
void TmpFnc(void)
{
CTmpColSens[Counter]->CShowSt();
Counter++;
}
{
CTmpColSens[Counter]->CShowSt();
Counter++;
}
Заметил, что поля не инициализируется значениями указанными в конструкторе, т.е. он не вызывается вовсе?
Ну а по поыоду использования контейнеров: прочитав про них, нонял, что именно его и пытаемся сейчас реализовать.
"пытаемся" :D - да только неизвестно что получается.
Я как-то в порядке самообучения написал контейнер-массив, аналогичный DynamicArray.
В общем, что получилось:
Код:
template <class T> void __fastcall TtDynArray<T>::Items_Create (int New_Count)
{
//DONE -cСоздание -oДинамический массив: Создание элементов при увеличении массива
for (int i = _fCount; i < New_Count; i++)
new (_fItems+i) T;
}
//---------------------------------------------------------------------------
template <class T> void __fastcall TtDynArray<T>::Items_Delete (int New_Count)
{
//DONE -cУдаление -oДинамический массив: Удаление элементов при уменьшении массива
for (int i = _fCount; --i >= New_Count;)
(_fItems+i)->~T();
}
//---------------------------------------------------------------------------
template <class T> void __fastcall TtDynArray<T>::SetCount (int Count)
{
//DONE -cЗапись свойства -oДинамический массив: Изменение количества элементов
this->Test_Count (Count);
if (Count == _fCount)
return;
// Изменение кол-ва памяти, выделенной под массив
this->Items_Delete (Count);
_fItems = (T*) realloc (_fItems, sizeof (T) * Count);
this->Items_Create (Count);
// Изменение параметров массива
_fCount = Count;
}
{
//DONE -cСоздание -oДинамический массив: Создание элементов при увеличении массива
for (int i = _fCount; i < New_Count; i++)
new (_fItems+i) T;
}
//---------------------------------------------------------------------------
template <class T> void __fastcall TtDynArray<T>::Items_Delete (int New_Count)
{
//DONE -cУдаление -oДинамический массив: Удаление элементов при уменьшении массива
for (int i = _fCount; --i >= New_Count;)
(_fItems+i)->~T();
}
//---------------------------------------------------------------------------
template <class T> void __fastcall TtDynArray<T>::SetCount (int Count)
{
//DONE -cЗапись свойства -oДинамический массив: Изменение количества элементов
this->Test_Count (Count);
if (Count == _fCount)
return;
// Изменение кол-ва памяти, выделенной под массив
this->Items_Delete (Count);
_fItems = (T*) realloc (_fItems, sizeof (T) * Count);
this->Items_Create (Count);
// Изменение параметров массива
_fCount = Count;
}
Это как раз те самые методы, которые реализуют изменения количества элементов массива.
А проще всего - сделай наследование от конкретной реализации шаблона DynamicArray, или используй его как поле объекта.
Цитата: Rize
Заметил, что поля не инициализируется значениями указанными в конструкторе, т.е. он не вызывается вовсе?
Судя по описанию твоих классов, ты не очень заботишся чтобы конструкторы классов назывались тагже, как класс.
Цитата: Rize
Функция TmpFnc срабатывает один раз, а на второй проход ломается с ошибкой:
...
Попробуй так:
Код:
class CSensor
{
private:
float CSensorValue;
String CSensorName;
public:
CSensor()
{
CSensorValue = 123456;
CSensorName = "!ERROR!";
};
/*CValStruct*/void CShowSt(){ShowMessage("BLA");};
};
class CSensorsManager
{
private:
CSensor* CSensorsCollection[];
CSensor* CTmpColSens[10];
int Count4SenCol;
int Counter;
public:
CSensorsManager()
{
Count4SenCol = 0;
Counter = 0;
};
void TmpFnc(void)
{
CSensorsCollection[Count4SenCol] = new CSensor();
Count4SenCol++;
}
void SomeDo()
{
for(int i(0) ; i < Count4SenCol ; i++)
CSensorsCollection->CShowSt();
}
};
{
private:
float CSensorValue;
String CSensorName;
public:
CSensor()
{
CSensorValue = 123456;
CSensorName = "!ERROR!";
};
/*CValStruct*/void CShowSt(){ShowMessage("BLA");};
};
class CSensorsManager
{
private:
CSensor* CSensorsCollection[];
CSensor* CTmpColSens[10];
int Count4SenCol;
int Counter;
public:
CSensorsManager()
{
Count4SenCol = 0;
Counter = 0;
};
void TmpFnc(void)
{
CSensorsCollection[Count4SenCol] = new CSensor();
Count4SenCol++;
}
void SomeDo()
{
for(int i(0) ; i < Count4SenCol ; i++)
CSensorsCollection->CShowSt();
}
};
И кстати, после объявления класса ОБЯЗАТЕЛЬНО ставиться символ ";".