首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >链接列表的深拷贝

链接列表的深拷贝
EN

Stack Overflow用户
提问于 2014-05-25 00:26:48
回答 2查看 89关注 0票数 0

我有双链接列表,m_Terminal1是列表的开始,m_Terminal2是列表的末尾。这是我的密码

代码语言:javascript
复制
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。有人能帮我吗?提前谢谢你

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-25 00:35:04

您正在创建两个与第一个停止具有相同名称的对象(m_Terminal1m_Terminal2),并将停止列表添加到m_Terminal2中。因为变量指向内存中不同的位置(通过new调用),所以它们不是相同的项,最终,m_Terminal2将有完整的列表,而m_Terminal1只会有第一个停止。在此过程中,您不会将最后一站存储在m_Terminal2中。

解决这一问题的一种方法是,最初只初始化和存储第一个停止,遍历并添加所有停止,并存储(而不是重新初始化)最后一个停止。

代码语言:javascript
复制
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;
}
票数 0
EN

Stack Overflow用户

发布于 2014-05-25 01:05:46

您应该重用已经编写的代码。您编写了一个Add()函数,那么为什么不使用它呢?

首先,修正Add()函数,以便它调用另一个函数,其中唯一的目的是在序列末尾添加一个节点:

代码语言:javascript
复制
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()函数的原因是,复制构造函数(和赋值操作符)现在变得非常容易编写。

代码语言:javascript
复制
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()函数中编写的代码要简单得多,在逻辑上也更有意义。

请注意,除了复制构造函数之外,还必须编写赋值运算符。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23850916

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档