Reputation: 582
I have the following code where a waitline object is created to keep track of the people in line in the form of nodes. The enterLine()
function adds a person to the line and points the node before them to their own node. exitLine()
removes the first person in the line.
#include <iostream>
#include <string>
using namespace std;
struct node {
string val;
node *next; // this will be the pointer to the person behind this person
};
class waitline {
public:
waitline() {};
void enterLine(string x);
string exitLine();
int size() { return len; };
bool isEmpty() {
if (len == 0) return true; else return false;
};
void printLine();
private:
node * front = NULL, *rear = NULL;
int len = 0;
};
void waitline::enterLine(string x) {
if (len == 0) {
front = new node;
rear = front;
front->val = x;
front->next = NULL;
len++;
}
else {
rear->next = new node; // rear is the last person in line
rear = rear->next; //reset rear to the new node.
rear->val = x;
rear->next = NULL;
len++;
}
};
string waitline::exitLine() {
string s;
if (len == 0) { // no one in line
cout << "error-no one in line\n";
return "";
}
else {
s = front->val;
front = front->next;
len--;
return s;
}
};
void waitline::printLine() {
node *temp;
cout << "FRONT OF LINE\n";
temp = front;
while (temp != NULL) {
cout << temp->val << endl;
temp = temp->next;
}
};
int main() {
waitline w, w2;
w.enterLine("Joe");
w.enterLine("Mary");
w.enterLine("Mikey");
w2 = w;
cout << "waiting line w2 is\n";
w.printLine();
cout << w.exitLine() << " was served\n";
w2.enterLine("Susie");
w.enterLine("Juan");
w.enterLine("Nguyen");
cout << w.exitLine() << " was served\n";
w.printLine();
cout << w.size() << endl;
w2.printLine();
return 0;
}
I expect w2 to only hold the first 3 values (Joe, Mary, and Mikey) as well as Susie, who was explicitly added to w2. When printing w2, however, it gives the output I expect from printLine(w)
.
Upvotes: 0
Views: 87
Reputation: 9068
I want to state erenon's answer a little differently. The problem is this line of code:
w2 = w;
What this does is copy the structure of w into w2. That is, w2.front, w2.rear, and w2.length are copied. The data they point to is not.
In other words, w2.front points to the exact same node as w.front, not a copy of it. So if you modify w2.front->next, you're also at the same time modifying w.front->next, as it's the exact same space in memory.
This is almost certainly not what you want.
If you are going to do w2 = w, then you need to implement a copy operator. You can google for examples of how to write that. But basically what you would do is iterate over the list of nodes, creating a duplicate list, so that neither waitline actually points to the same list of node objects.
Assuming that's what you want -- a distinct NEW LINE, but based on the same strings as the original line, so that changes to one do not affect the other.
I wouldn't do it that way, though. I'd write another method in waitline:
void copyFrom(waitline &orig) {
for (node *ptr = orig.front; ptr != NULL; ptr = ptr->next) {
enterLine(ptr->val);
}
}
Then instead of the copy operation, I would do:
w2.copyFrom(w);
That's almost the same thing as writing a copy operator, but as you're new to this, you don't need to learn copy operator semantics while also learning about pointers.
Upvotes: 0
Reputation: 19128
w2 = w
does a shallow copy: it copies the pointers, but not the pointed to objects. Therefore, the changes to those pointed objects made via w
can be observed via w
as well. You need to do a deep copy, e.g: by implementing operator=
properly.
The rule of 3/5/0 gives a good explanation on the required members a resource handling object needs to implement.
Otherwise, as the other commenters point out: there are several memory management issues in the code. Unless this is some sort of homework, or a deliberate attempt to learn how pointers work, it'd more efficient to use standard containers, e.g: std::vector
, std::dequeue
or std::list
.
Upvotes: 3