我有以下代码,其中创建了一个等待线对象,以节点的形式跟踪人员。 enterLine()
函数将一个人添加到行中,并将他们之前的节点指向自己的节点。 exitLine()
删除该行中的第一个人。
#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;
}
我希望w2只保留前3个值(Joe,Mary和Mikey)以及Susie,后者已显式添加到w2。但是,在打印w2时,它将提供我期望从printLine(w)
获得的输出。
答案 0 :(得分:3)
w2 = w
进行浅表复制:复制指针,但不复制指向对象的指针。因此,也可以通过w
来观察通过w
对那些指向对象的更改。您需要进行深层复制,例如:通过正确实现operator=
。
rule of 3/5/0对资源处理对象需要实现的必需成员进行了很好的解释。
否则,正如其他评论者指出的那样:代码中存在几个内存管理问题。除非这是某种家庭作业,或者是故意学习指针的工作原理,否则使用标准容器(例如:std::vector
,std::dequeue
或std::list
)会更有效。>
答案 1 :(得分:0)
我想以不同的方式陈述erenon的答案。问题是这行代码:
w2 = w;
这是将w的结构复制到w2中。也就是说,复制了w2.front,w2.rear和w2.length。他们指向的数据不是。
换句话说,w2.front指向与w.front完全相同的节点,而不是它的副本。因此,如果修改w2.front-> next,则同时修改w.front-> next,因为它与内存中的空间完全相同。
这几乎肯定不是您想要的。
如果要执行w2 = w,则需要实现一个复制运算符。您可以在google上找到如何编写示例。但是基本上,您要做的是遍历节点列表,创建一个重复列表,这样,等待线都不会真正指向相同的节点对象列表。
假设这就是您想要的-一个独特的NEW LINE,但是基于与原始行相同的字符串,因此对一个行的更改不会影响另一个。
不过,我不会那样做。我会在等待线上写另一个方法:
void copyFrom(waitline &orig) {
for (node *ptr = orig.front; ptr != NULL; ptr = ptr->next) {
enterLine(ptr->val);
}
}
然后我将执行复制操作,而不是复制操作:
w2.copyFrom(w);
这与编写复制操作符几乎相同,但是由于您是新手,因此无需学习复制操作符语义,也无需了解指针。