Теоретически, ваш конструктор копирования может записываться в цикле, при условии, что существуют правильные функции при извлечении из хэш-таблицы и добавление значения в хеш-таблицу. Если этих функций в настоящее время не существует, тогда было бы намного дороже, если бы вы все равно записывали эти функции, так как хеш-таблица была бы очень ограничительной, если бы не было способа повторить все значения.
Предположим, что у вас есть такие функции, в которых вы получаете Node*
в функциях get
. Также предположим, что getFirst()
извлекает головной узел, а getNext()
извлекает следующий узел, учитывая значение Node*
для начала. Конструктор копирования будет выглядеть примерно так:
Apple::Apple(const Apple& anotherApple)
{
Node* curNode = anotherApple.getFirst();
while (curNode)
{
addValue(curNode->key, curNode->value);
curNode = anotherApple.getNext(curNode);
}
}
Это требует, чтобы ваша реализации есть способ, чтобы получить первое значение в таблице, используя что-то вроде getFirst()
и итерации к следующей записи текущего узла с помощью функции getNext()
. Если не больше узлов, то getNext()
вернет NULL.
Преимущество написания конструктора копирования таким образом заключается в том, что вы повторно используете код, который, мы надеемся, был протестирован, а именно функцию addValue
, вместо того, чтобы в принципе переписать addValue
снова. Кроме того, вероятность возникновения ошибки практически отсутствует, поскольку вы просто вызываете уже существующие функции.
Недостаток написания конструктора копирования таким образом заключается в том, что сложность с точки зрения runtiime может быть медленнее, чем попытка создания всех внутренних компонентов «с нуля» с использованием большого количества манипуляций с указателями (как это сделал один из предыдущих ответов).
Так взвесить разницу, безопасность по скорости. Возможно, нет проблем с безопасностью, используя безопасный подход.
Для оператора присваивания, если у вас есть рабочий конструктор копирования и рабочий деструктор, то это все, что вам нужно сделать:
#include <algorithm>
//...
Apple& Apple::operator=(const Apple& anotherApple)
{
Apple temp(anotherApple);
std::swap(temp.array, array);
std::swap(temp.tableSize, tableSize);
std::swap(temp.count, count);
return *this;
}
Это использует copy/swap idiom. Опять же, для этого требуется правильный конструктор копирования и правильный деструктор (никаких ошибок в этих двух функциях).
массив = новый узел * [таблицаSize]. Но вам нужно знать количество элементов, которые будут помещены в каждую строку. Для выполнения глубокой копии необходимо выполнить итерацию по другому элементу apple.array и скопировать все элементы по одному для каждой строки. Это имеет смысл для вас? –
@pravar, как бы вы сделали глубокую копию. Потому что мне нужно скопировать каждый связанный узел по каждому индексу массива? – programmingblues
Совет - сосредоточьтесь только на конструкторе копирования. Оператор присваивания можно легко записать, как только конструктор копирования (и деструктор) работают правильно. Во-вторых, ваш массив должен знать, сколько элементов нужно выделить первым, и это должно быть доступно из 'anotherApple'. – PaulMcKenzie