我有双链接列表,m_Terminal1是列表的开始,m_Terminal2是列表的末尾。这是我的密码
CBusLine(const CBusLine & orig){
m_Terminal1 = new TStop(orig.m_Terminal1 -> m_Name);
m_Terminal2 = new TStop(orig.m_Terminal1 -> m_Name);
TStop * tmpx = m_Terminal2;
TStop * copy = orig.m_Terminal1;
copy = copy ->m_Next;
while(copy != NULL){
TStop * copy_tmp = new TStop(copy->m_Name);
tmpx -> m_Next = copy_tmp;
copy_tmp -> m_Prev = tmpx;
tmpx = copy_tmp;
copy = copy->m_Next;
}不幸的是,它不起作用,当我想打印列表时,只有第一项。这是源文件http://pastebin.com/YCKyZ31K。有人能帮我吗?提前谢谢你
发布于 2014-05-25 00:35:04
您正在创建两个与第一个停止具有相同名称的对象(m_Terminal1和m_Terminal2),并将停止列表添加到m_Terminal2中。因为变量指向内存中不同的位置(通过new调用),所以它们不是相同的项,最终,m_Terminal2将有完整的列表,而m_Terminal1只会有第一个停止。在此过程中,您不会将最后一站存储在m_Terminal2中。
解决这一问题的一种方法是,最初只初始化和存储第一个停止,遍历并添加所有停止,并存储(而不是重新初始化)最后一个停止。
CBusLine(CBusLine & orig){
m_Terminal1 = new TStop(orig.m_Terminal1 -> m_Name);
TStop * tmpx = m_Terminal1;
TStop * copy = orig.m_Terminal1;
copy = copy ->m_Next;
while(copy != NULL){
TStop * copy_tmp = new TStop(copy->m_Name);
tmpx -> m_Next = copy_tmp;
copy_tmp -> m_Prev = tmpx;
tmpx = copy_tmp;
copy = copy->m_Next;
m_Terminal2 = tmpx;
}发布于 2014-05-25 01:05:46
您应该重用已经编写的代码。您编写了一个Add()函数,那么为什么不使用它呢?
首先,修正Add()函数,以便它调用另一个函数,其中唯一的目的是在序列末尾添加一个节点:
void CBusLine::Add(istream& is)
{
string line;
while(is.good())
{
getline(is, line);
if(line == "")
continue;
AddInternal(line);
}
}
void CBusLine::AddInternal(string& line)
{
TStop * n = new TStop(line);
if(m_Terminal2 == NULL){
m_Terminal1 = n;
m_Terminal2 = n;
}
else{
m_Terminal2 -> m_Next = n;
n -> m_Prev = m_Terminal2;
m_Terminal2 = n;
}
}分解Add()函数的原因是,复制构造函数(和赋值操作符)现在变得非常容易编写。
CBusLine(const CBusLine & orig)
{
TStop *startTerm = orig.m_Terminal1;
while ( startTerm != orig.m_Terminal2 )
{
AddInternal( startTerm->m_name);
startTerm = startTerm->m_Next;
}
}当然,AddInternal必须正确工作。我假设m_Terminal1和m_Terminal2是链接列表的开始和结尾。
考虑到AddInternal()工作正常,复制构造函数是一个简单的循环,从开始到结束,然后用终端的字符串数据调用AddInternal()。这比重新创建已经在Add()函数中编写的代码要简单得多,在逻辑上也更有意义。
请注意,除了复制构造函数之外,还必须编写赋值运算符。
https://stackoverflow.com/questions/23850916
复制相似问题