【问题标题】:Deleting specific class objects stored in an array [closed]删除存储在数组中的特定类对象[关闭]
【发布时间】:2013-01-07 06:58:06
【问题描述】:

我的代码有问题,我想知道是否有人可以看看,我创建了一个函数来从数组中删除特定元素。我使用线性搜索来查找元素,然后用后面的元素覆盖我想要删除的元素,因为我还没有找到专门删除元素的方法。我的问题是代码并没有真正起作用,因为元素没有被覆盖,还有一种方法可以在元素被覆盖后在数组中留下一个空格。

下面是我的代码:

void deleteinfo()
{
    string search ;
    int found ;

    cout << "\n Delete A Player's Information \n\n" ;
    cout << "Please Enter The Player's Last Name : " ;
    cin >> search ;

    found=linsearch(search);

    if (found==-1)
    {
        cout << "\n There is no player called " << search ;
    }
    else
    {
        player[found].getFirstName() = player[found + 1].getFirstName() ;
        player[found].getLastName() = player[found + 1].getLastName() ;
        player[found].getAge() == player[found + 1].getAge() ;
        player[found].getCurrentTeam() = player[found + 1].getCurrentTeam() ;
        player[found].getPosition() = player[found + 1].getPosition() ;
        player[found].getStatus() = player[found + 1 ].getStatus() ;

        cout << "\n Player has been deleted." ;
    }

    cin.get() ;

    menu() ;
}


int linsearch(string val)
{
    for (int j=0; j <= 3; j++)
    {
        if  (player[j].getLastName()==val)
         return j ;         
    }
        return -1 ;
}

【问题讨论】:

  • 让陌生人发现你的代码中的错误是没有效率的。请使用调试器(或添加打印语句)帮助隔离问题,然后创建minimal test-case
  • 几乎所有的容器,如std::vectorstd::list等,都有办法从中间移除一个元素。 C 风格的数组容易出错且乏味。
  • 我不能使用矢量和列表等标题。我的编码方式很有限。谢谢
  • 就像 aschepler 已经说过的,考虑使用标准容器。或者,如果您必须手动执行此操作,请使用链表,或者(这可能正是您想要的),将数组中的指针值设置为 NULL。 (假设您使用的是指针数组而不是“静态”对象)
  • 是否也需要将found + 2的内容移动到found + 1

标签: c++ arrays class object


【解决方案1】:

您需要做的就是将所有跟在您要删除的元素后面的所有元素复制到左边一个位置,最后更新数组的新长度。例如:

for (size_t i = found + 1; i < player_length; ++i) {
    player[i - 1] = player[i];
}
--player_length;

player 数组中的对象必须是可复制的。我假设您在某处有一个变量来保存数组的当前长度(“长度”是指它当前有多少玩家,而不是它的总容量。)

【讨论】:

  • 我怎么知道对象是否可复制?
  • @tarantino 如果代码编译,它们是可复制的。否则你会得到错误。不可复制对象的一个​​例子是它们有一个已删除或私有的赋值运算符。
  • 我已经尝试过你的方法,但我仍然没有得到正确的输出并且代码编译没有错误。谢谢你的帮助
  • @tarantino 如果你认为你有一个可行的方法来解决这个问题,但无法找出问题所在,请提出一个新问题。
【解决方案2】:

这只是一个示例,您可以如何解决此问题。我假设您有一个静态长度数组(最大玩家数)。

Player *Players[MAX_PLAYERS];          //Array with pointers to Player objects.
for(int i = 0; i < MAX_PLAYERS; ++i)
    Players[i] = new Players(x, y, z); //Fills the array with some data.

现在为您擦除:

if(found > 0) {
    delete Players[found];             //Destroys the object in question.
    for(int i = found; i < MAX_PLAYERS - 1; ++i)
        Players[i] = Players[i + 1];   //Moves the entire list up by one.
    Players[MAX_PLAYERS - 1] = NULL;   //Marks the new end of the list.
}

这个小 sn-p 不会“复制”整个对象,而是将它们在数组中向上移动(不重构任何对象)。

当您遇到第一个 NULL 指针(并且最迟在 MAX_PLAYERS 处)时,该数组位于它的“末尾”,这说明了您的“空白空间”。或者,您可以省略“向上移动”,只需销毁对象并将指针设置为 NULL。这样一来,你就会知道那里没有玩家。

【讨论】:

  • 我怎么知道对象是否可复制?
  • @tarantino 对象本身根本不需要复制。您正在移动整个对象,而不仅仅是数据。你知道指针是如何工作的吗?简而言之,它们“指向”数据。因此,无需将对象移动到任何地方,您只需告诉新的“下一个”:现在指向该对象。啊,是的,要从指针访问对象,您需要使用-&gt; 而不是.
  • 谢谢,我会看看使用指针
  • @tarantino 请记住接受一个答案,如果它帮助你回答了你的问题。
猜你喜欢
  • 1970-01-01
  • 2019-07-13
  • 1970-01-01
  • 2021-07-21
  • 1970-01-01
  • 2011-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多