programmingblues
programmingblues

Reputation: 113

copy constructors for hash tables

Im having trouble with writing a copy constructor for my hashtable. I already have trouble with copy constructors with linked objects alone. How can I implement a copy constructor and a assignment operator with the following functions:

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


}

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


}

I know it would be something along the lines of:

tableSize = anotherApple.tableSize;
count = anotherApple.count;
array = new *anotherApple.array; //idk if this is right for dynamically created array of pointers

Upvotes: 0

Views: 3393

Answers (2)

PaulMcKenzie
PaulMcKenzie

Reputation: 35440

Theoretically, your copy constructor can be written in a loop, providing that the proper functions exist in retrieving from a hash table, and adding a value to a hash table. If these functions currently don't exist, then it would be worth a lot more if you did write these functions anyway, as the hash table would be very restrictive if there was no way to iterate through all of the values.

Assume that you have such functions, where you retrieve a Node* in the get functions. Also assume that getFirst() retrieves the head node, and getNext() retrieves the next node, given a Node* value to start from. The copy constructor would look something like this:

Apple::Apple(const Apple& anotherApple)
{
    Node* curNode = anotherApple.getFirst();
    while (curNode)
    {
       addValue(curNode->key, curNode->value);
       curNode = anotherApple.getNext(curNode);
    }
}

This requires that your implementation has a way to get the first value in the table using something like getFirst(), and iterate to the next entry of the current node by a function called getNext(). If no more nodes, then getNext() would return a NULL.

The advantage to writing the copy constructor this way is that you reuse code that hopefully has been tested, namely the addValue function, instead of having to basically rewrite addValue over again. In addition, there is little to no chance of an error occurring, since you're just calling functions that exist already.

The disadvantage to writing the copy constructor this way is that the complexity in terms of runtiime may be slower than attempting to create the entire internals "from scratch" using a lot of pointer manipulation (like one of the previous answers has done).

So weigh the differences, safety over speed. Maybe there is no speed issues using the safe approach.


For the assignment operator, if you have a working copy constructor and a working destructor, then this is all you need to do:

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

This uses the copy / swap idiom. Again, this requires a correct copy constructor and a correct destructor (no bugs whatsoever in these two functions).

Upvotes: 1

Pravar Jawalekar
Pravar Jawalekar

Reputation: 605

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

Upvotes: 1

Related Questions