复制哈希表的构造函数

copy constructors for hash tables

本文关键字:构造函数 哈希表 复制      更新时间:2023-10-16

我在为哈希表编写复制构造函数时遇到问题。我已经在单独使用链接对象的复制构造函数时遇到了问题。如何使用以下函数实现复制构造函数和赋值运算符:

//copy constructor
Apple::Apple(const Apple& anotherApple){

}
//assignment operator
Apple& Apple::operator = (const Apple& anotherApple){

}

我知道这将是一个类似的东西

tableSize = anotherApple.tableSize;
count = anotherApple.count;
array = new *anotherApple.array; //idk if this is right for dynamically created array of pointers
Apple::Apple(Apple const & anotherApple)
{
     // allocate an array to hold pointers to Node
     array = new Node*[tableSize];
     for(int i=0; i<tableSize; i++)
     {
        Node* src = anotherApple.array[i];
        Node* dest;
        if (src == NULL)
        {
           array[i] = NULL;
           continue; // no data to copy, continue to next row
        }

        // set array[i] since there is at-least one element
        dest = new Node;
        dest->data = src->data;
        array[i] = dest;
        src = src->next;
        while(src != NULL)
        {
           Node* n = new Node;
           dest->next = n;
           dest = n;
           dest->data = src->data;
           src = src->next;
        }
        dest->next = NULL;
     }
  }

理论上,您的复制构造函数可以在循环中编写,前提是从哈希表中检索并向哈希表中添加值时存在适当的函数。如果这些函数目前还不存在,那么如果你无论如何都写这些函数,那就更有价值了,因为如果没有办法迭代所有值,哈希表将非常受限。

假设您有这样的函数,在get函数中检索一个Node*。还假设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。此外,由于您只是在调用已经存在的函数,因此发生错误的可能性很小甚至没有。

以这种方式编写复制构造函数的缺点是,运行时的复杂性可能比尝试使用大量指针操作"从头开始"创建整个内部结构要慢(就像前面的一个答案所做的那样)。

因此,权衡差异,安全高于速度。使用安全方法可能不存在速度问题。


对于赋值运算符,如果您有一个可工作的复制构造函数和一个可运行的析构函数,那么这就是您所需要做的:

#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;
}

这使用了复制/交换习惯用法。同样,这需要正确的复制构造函数和正确的析构函数(这两个函数中没有任何错误)。