Home > Software design >  array transfer constructor function c
array transfer constructor function c

Time:08-24

I am trying to learn constructors in c . I am working on a list that I defined. I managed to get the copy constructor working, but I have problems with the array transfer constructor. Any help will be appreciated. Thanks!

The array transfer constructor supposedly should take in an array and a size(int) and output a list with that size.

ex: input: data = {1,3,5,6};int = 5;output = {1,3,5,6,0} edit: change n to i

#include <iostream>

using namespace std;
class list_element{
public:
    list_element(int n = 0,list_element* ptr = nullptr):
        d(n),next(ptr){}
    int d;
    list_element* next;

};

class List{
public :
    List():head(nullptr),cursor(nullptr){}
    List(const int* arr, int n); // copy array transfer data
    List(const List& lst); //copy constructor
    void prepend(int n);
    int get_element() 
    {
        return cursor->d;
    }
    void advance() { cursor = cursor->next; }
    void print();
    ~List();    //delete
private:
    list_element* head;
    list_element* cursor;
};


//transfer array 
List::List(const int* arr, int n) {
    List temp;
    int i = 0;
    while (i < n)
    {
        head = new list_element(arr[i], head);
          i;
    }

}

//delete 
List::~List(){
    for (cursor = head; cursor != 0;)
    {
        cursor = head->next;
        delete head;
        head = cursor;
    }

}
//deep copy constructor
List::List(const List& lst) {
    if (lst.head == nullptr)
    {
        head = nullptr; cursor = nullptr;
    }
    else
    {
        cursor = lst.head;
        list_element* h = new list_element();
        list_element* previous;
        head = h;
        h->d = lst.head->d;
        previous = h;
        for (cursor = lst.head; cursor != 0;)
        {
            h = new list_element();
            h->d = cursor->d;
            previous->next = h;
            cursor = cursor->next;
            previous = h;
        }
        cursor = head;
    }
}


void List::prepend(int n)
{
    if (head == nullptr)
        cursor = head = new list_element(n, head);
    else
        head = new list_element(n, head);
}

void List::print()
{
    list_element* h = head;
    while (h != 0)
    {
        cout << h->d << ',';
        h = h->next;
    }
    cout << "###" << endl;
}


int main()
{
    List a, b;
    //change size
    int data[10] = { 1,3,5,7};
    List d(data, 10);
    d.print();
    return 0;

}

CodePudding user response:

Main Question

With regards to your 'from_array' constructor, you have a temporary List variable that you are not using and is also unnecessary.

Second you are assigning the head pointer each time meaning that by the end of the constructor call, head now points to the last element you constructed.

Third your list_element constructor is taking the old head pointer which points to the previous element meaning the list is tries to advance from the bottom element upwards through the list, causing the reversed read you mentioned in a comment.

You can fix this two ways. First, you could reverse the order you read the input array so it constructs your linked-list back to front.

List::List(const int* arr, int n)
{
    int i = n - 1;
    list_element* it = new list_element(arr[i], nullptr);  ///< Last element
    --i;
    
    while (i > -1)
    {
        it = new list_element(arr[i], it);
        --i;
    }
    head = it;  ///< assign head to the last instance of it.
    it = nullptr;
}

However, there is a better why that expresses the linking of the elements more intuitively. First you need to pre-construct the next element and give it some default values (I didn't bother implementing a default constructor for list_element but you might want to.) and assign it to next, then assign head to a new list_element passing in the pointer to next. increment i so that you can assign next's value to the second value in the array. Finally incremenet i again so we can loop through the rest of the array. Finally, in the while loop, copy next into a variable called prev. Assign next to a new list_element with the value from the array and a nullptr. Finally assign prev->next to the new next pointer and increment i.

list_element::list_element()

List::List(const int* arr, int n)
{
    int i = 0;

    list_element* next = new list_element(0, nullptr);
    head = new list_element(arr[i], next);
      i;
    next->d = arr[i];
      i;

    while (i < n)
    {
        list_element* prev = next;
        next = new list_element(arr[i], nullptr);
        prev->next = next;
          i;
    }

}

Side Notes

Because you stated you are tying to learn about C constructors (and I'm assuming data structures) I would suggest starting with a static array type similar to std::array as it's constructors a bit more trivial to implement or even just start with simple classes/struct that just hold simple data like a few ints or whatnot as you can get an idea for the semantics around the various constructors in C .

Also, the C standard library has two linked list types (std::list and std::foward_list)

Finally, you might be better off using a std::initializer_list instead of a raw array as this give you iterators to the data you want to copy which is a bit nicer to use.

Best of luck in your learning journey.

CodePudding user response:

Try to avoid using variable names like 'n', which could be very confusing.

In your copy constructor for transferring the array, you should not access the array using 'n', which is the desired size of the transferred array, nor increment it.

Additionally, sizeof(arr) doesn't work as you would expect. You are querying the size of the pointer.

  • Related