Ваше первое предложение уже показывает всю путаницу:
Привет, у меня есть массив, который передается через функцию и присваивается члену класса, который является указателем.
Вы не можете "передать массив". Вы можете передавать указатели или ссылки на массивы или элементы массива в функции. Тип параметра array в конструкторе для ClassA фактически является типом указателя. Это правила C, которые уже запутывают достаточно людей. Обязательно ознакомьтесь с хорошими учебниками по массивам и указателям.
Вот что действительно происходит в вашем коде:
- Вы создаете массив с автоматической продолжительностью хранения внутри первой функции,
- Вы заполняете его данными.
- Вы передаете указатель на первый элемент массива в конструктор ClassA :: ClassA
- Итерация завершена, массив перестает существовать, и шаги 1-3 повторяются еще 4 раза
Проблема: все объекты ClassA имеют недопустимый элемент-указатель, потому что все массивы, на которые они ссылались, теперь исчезли.
Если вы хотите, чтобы эти массивы пережили свою область, это требует динамического выделения. Вы можете динамически выделять массив и «передавать владение» объекту ClassA . Под «владением» мы обычно подразумеваем ответственность за управление и удаление массива. Это возможно, и другие ответы покажут вам, как к этому подойти. Но они на самом деле неполные. Видите ли, если вы хотите, чтобы объект класса управлял таким ресурсом, как память, вам нужно сделать больше, чем просто предоставить деструктор. Вы также должны позаботиться о копировании. Это означает, что конструктор копирования и оператор присваивания. Поскольку вы не только создаете объект класса ClassA, но и используете его в качестве аргумента для функции push_back списка, список создаст копию и сохранит / будет управлять этой копией. Таким образом, если вы все еще хотите заставить ClassA правильно управлять буфером, сохраняя простой (немой) указатель, вы должны написать ctor копии, оператор присваивания и деструктор, потому что в противном случае они были бы сгенерированы компилятором. А сгенерированные компилятором просто копируют по элементам. Полагаю, вы не хотите, чтобы два отдельных объекта ClassA совместно использовали один и тот же буфер, верно?
Вместо обработки необработанных указателей вы можете просто использовать вектор как ClassA member:
class ClassA
{
std::vector<unsigned char> buffer;
public:
ClassA(unsigned char const* begin, unsigned char const* end)
: buffer(begin,end)
{}
};
:
:
void firstFunction()
{
for(int i = 0; i < 5; i++) {
unsigned char buffer[3000];
somePopulationFunction(&buffer);
classAcollection.push_back(ClassA(buffer+0,buffer+3000));
}
}
Это работает, потому что std :: vector не ведет себя как указатель. Если вы копируете вектор, копия будет управлять своими собственными элементами. Там нет обмена. В этом отношении вектор работает больше как обычный int или double. Обычно это реализуется в терминах указателей. Но это похоже на «обычный тип значения».
Здесь мы мало что можем сделать. ClassA должен быть копируемым, если вы хотите поместить ClassA объекты в список. Поэтому трудно избежать копирования и в то же время избежать совместного использования буферов между ClassA объектами.
В C ++ 0x (кодовое имя для будущего стандарта C ++) вы сможете сделать это:
class ClassA
{
std::vector<unsigned char> buffer;
public:
ClassA(unsigned char const* begin, unsigned char const* end)
: buffer(begin,end)
{}
ClassA(ClassA const&) = default;
ClassA(ClassA &&) = default;
ClassA& operator=(ClassA const&) = default;
ClassA& operator=(ClassA &&) = default;
};
Это создаст класс, который будет копируемым и «подвижным». Класс с включенным перемещением обычно очень эффективно передается из и в функции. В вашем примере объект ClassA является временным объектом. Как таковой, он может быть быстро перемещен в список без какого-либо ненужного копирования объектов буфера. Но это только то, что тебя дразнит. C ++ 0x еще не официально.