2016-10-11 6 views
2

Я не понимаю исходных указателей достаточно хорошо и, к сожалению, я не разрешено использовать <vector> s, поэтому я не могу понять, как написать параметризованный конструктор класса с массивом других объектов класса, его собственности.Как передать динамический массив объектов параметризованному конструктору другого класса?

class A{ 
    ... 
}; 

class B{ 
    int size; 
    A *arr; 
    ... 
    B(int, const A *); // am I declaring this right? 
} 

... 

B::B(int size_, const A *arr_) { // this is the constructor I'm trying to write 
    size = size_; 
    if (arr != nullptr) delete[] arr; 
    arr = new A[size]; 
    memcpy(arr, arr_, sizeof(A) * size); 
} 

Как передать этот аргумент, не испортив память? Код выше не работает должным образом, поэтому я хотел бы услышать несколько советов. Мне не удалось найти решение Google, хотя мне кажется, что мой вопрос уже ответил, извиняюсь в этом случае.

Я не могу использовать сейф std::. Мне нужно выяснить, как заставить его работать, используя выделение памяти вручную из C. Ой, я имею в виду C++, спасибо, что указали это.

Так вот конструктор, который работает для меня до сих пор:

B::B(int size_, const A *arr_) { 
    size = size_; 
    arr = new A[size_]; 
    for (int i = 0; i < size; i++) arr[i] = arr_[i]; 
} 

Спасибо за время каждого!

+0

Вам необходимо предоставить полный тестовый пример. См. Здесь: http://stackoverflow.com/help/mcve. Недостаточно информации в коде, который вы указали, чтобы сообщить вам, что не так. – xaxxon

+1

Вы можете использовать 'std: array'? –

+1

'if (arr!= nullptr) delete [] arr; 'маловероятно, что вы хотите в своем конструкторе. На самом деле это просто неправильно. И использование 'memcpy' просто неверно, если вы не знаете, что' A' тривиально копируется. – jxh

ответ

3

В конструкторе:

if (arr != nullptr) delete[] arr; 

arr является членом класса, который не инициализирован в этой точке. Это указатель на мусор, который может быть чем-то иным, чем nullptr, и это попытается сделать delete указателем мусора. Очевидно, это далеко не так.

Просто удалите это. Ваш конструктор устанавливает size и arr, и это все, что ему нужно. Существующих значений size и arr не беспокоиться: вы строите новый объект.

memcpy(arr, arr_, sizeof(A) * size); 

Это будет работать только если Ais a POD. Вместо этого используйте std::copy(), что во всех случаях будет правильным. Если вы не можете использовать std::copy(), кроме того, вам не разрешено использовать std::vector, тогда напишите for-loop, чтобы скопировать эти данные вручную.

+1

Стоит отметить, что это все еще не очень удобно, поскольку он по умолчанию создает A, а затем копирует-присваивает, но он достаточно хорош для уровня, который OP выглядит в. –

0

Нет необходимости проверять, является ли arr NULL в конструкторе, потому что для arr еще не назначено.

memcpy не используется для копирования классов, поскольку классы обычно имеют функции-члены, которые хранятся в виде указателей на функции. ваш оператор memcpy не должен использоваться, поскольку он будет перезаписывать указатели на объекты, созданные в arr при выполнении новой команды A [size] и не позволят классу B выполнить правильно.

Использование цикла for для итерации через arr_ и копирования только данные из A от arr_ до arr - это путь.

Например, в цикле for вы можете сделать, arr [i] = arr_ [i], где i - индекс в цикле for. Если класс A не имеет перегруженного оператора присваивания, произойдет мелкая копия переменных-членов. Если мелкая копия неприемлема, тогда в классе А должен быть создан перегруженный оператор присваивания, если он не существует.

Смежные вопросы