appending a linklist node that has a linklist as a member

Pages: 12
I was told that template copy constructors was a no no(not that I cant use one but its a bad practice to do so).

It isn't bad practice. If you wish to support value/copy semantics and your class is managing its own memory, it is necessary or you end up destroying objects multiple times.

http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three

I haven't checked your code to see if there is use of the copy assignment operator, but I wouldn't surprised if there was one. You'll probably need to supply that too.


Also I'm not sure where exactly I would use it. Should I copy the CD temp before I pass it to the CDList.insertNode()?
LinkList::insertNode takes it's argument by value. The compiler is already making a copy when you call it. It just happens to be using the inadequate defaulted copy constructor since you didn't supply your own.
Last edited on
Also, Am I going about this the hard way. What I mean is there a simpler way of coding the addCD() function so that passing data and adding these nodes to the linked lists is less...cantankerous?

Thanks for the spelling correction. I hadn't even noticed. LOL!
Been working on this all day and results are the same..crash!! I've been working on a copy constructor and I think that it works (only because I can step threw it in the debugger and I get no exceptions or errors) But I'm going to post it because I'm still having the same problem(the program trying to free already freed memory during clean up). I think the problem is the copy assignment operator. I have been looking around and I cant seem to find a good example of one for a linked list. Here is what I have so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//***Copy Constructor***
template <class T> 
LinkList<T>::LinkList( const LinkList &listObj )
{

	head = NULL;

	ListNode *nodePtr;

	nodePtr = listObj.head;

	while(nodePtr != NULL)
	{
		 appendNode(nodePtr->value1);
		
		 nodePtr = nodePtr->next;
	}

}


here is what I have so far for the assignment operator:

1
2
3
4
5
template <class T>
LinkList<T>::LinkList& operator =(const LinkList &listObj)
{

}


Is my copy constuctor correct? What do I need to put in the assignment operator to get it to work? Do I need copy constructors for my derived CD class and if so does that mean I need one for the base class Media?

Thanks for the help so far. I feel like I'm getting close to making this work!(I'm definitely learning alot!!)
So the copy constructor dosen't work. I used a display function and it returned empty nodes. I need help with that too...Here is the display function for the LinkList class that I used. I added a call to it after the call to CDList.append() in main.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template <class T>
void LinkList<T>::displayList() const
{
	int count = 0;
	
	ListNode *nodePtr;

	nodePtr = head;

	while(nodePtr)
	{
		
		cout<<"Node index "<<count<<endl;
		cout<<nodePtr->value1<<endl;
	
		cout<<endl;

		count++;

		nodePtr = nodePtr->next;
	}
}


Guess I'm further off track than I thought.
Last edited on
So do I need a copy constructor for my other classes to get this to work? If so how do I write a copy constructor for a derived class?
Maybe you should start out with a simpler test in main:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
 // Note: search-and-replaced some method and variable names so they were easier
 // for me to read, or just plain fit better: example -> appendNode: the 
 // client code doesn't need to know anything about nodes, so a better name
 // is just append.

#include <iostream>

template <class T>
class LinkList
{
private:

    struct ListNode
    {
        T value1;
        struct ListNode *next;
    };

    ListNode *head;   // List head pointer

    void destroy(); // utility function

public:
    //***Constructor***
    LinkList();
    LinkList(const LinkList&);

    //***Destructor***
    ~LinkList();

    LinkList& operator=(LinkList);

    //***LinkList Operations***
    void append(T);
    // removed insert since it's invariants are violated by append.
    void display(std::ostream& stream) const;
};

template <class T>
void LinkList<T>::display(std::ostream& os) const
{
    unsigned index = 0;

    ListNode* current = head;

    while (current)
    {
        os << index++ << ": " << current->value1 << '\n';
        current = current->next;
    }
}

//Implimentation for LinkList
template <class T>
void LinkList<T>::destroy()
{
    ListNode* current = head;

    while (current)
    {
        ListNode* next = current->next;
        delete current;
        current = next;
    }

    head = nullptr;
}

//***Constructor***
template <class T>
LinkList<T>::LinkList() : head(nullptr)
{
}

template <class T>
LinkList<T>::LinkList(const LinkList<T>& list) : head(nullptr)
{
    ListNode* current = list.head;

    while (current)
    {
        append(current->value1);
        current = current->next;
    }
}

template <class T>
LinkList<T>& LinkList<T>::operator=(LinkList list)
{
    destroy();
    head = list.head;
    list.head = nullptr;

    return *this;
}


//***Destructor***
template <class T>
LinkList<T>::~LinkList()
{
    destroy();
}


//***LinkList Operations***
template <class T>
void LinkList<T>::append(T val1)
{
    ListNode* n = new ListNode;
    n->value1 = val1;
    n->next = nullptr;

    if (head == nullptr)
        head = n;
    else
    {
        ListNode* current = head;

        while (current->next)
            current = current->next;

        current->next = n;
    }
}

int main()
{
    LinkList<int> a;
    a.append(3);
    a.append(2);
    a.append(1);
    a.display(std::cout);
    std::cout << '\n';

    LinkList<int> b(a);      // copy constructor
    b.display(std::cout);
    std::cout << '\n';

    LinkList<int> c;
    c = a;                   // copy assignment
    c.display(std::cout);
    std::cout << '\n';
}


http://ideone.com/VLZuf6

So do I need a copy constructor for my other classes to get this to work?

From a brief inspection of your code, it appears that the defaulted versions should work for your other classes, provided LinkList is implemented correctly. I would like to emphasize, though, that the inspection was not thorough.

Topic archived. No new replies allowed.
Pages: 12