如何删除属于指针对象的指针向量中的项

时间:2018-03-08 06:32:19

标签: c++ pointers

我有一个播放列表,其中包含一个歌曲指针向量。

class Playlist {
public:
    Playlist();
    Playlist(string);
    vector<Song*> GetSongList() const;
private:
    vector<Song*> songs;
    string name;
};

函数GetSongList()如下:

vector<Song*> Playlist::GetSongList() const {
    return songs;
}

在我的主要方法中,我有一个播放列表指针向量:vector<Playlist*> playlists

我想删除特定播放列表中的歌曲指针,但我遇到了麻烦。这是我目前删除指定歌曲的代码:

Playlist* desiredPlaylist = playlists.at(index);
vector<Song*> temporarySongList = desiredPlaylist->GetSongList();
cout << "Pick a song index number to delete: ";
cin >> index;
temporarySongList.erase(tempSongList.begin() + index);

当我从矢量中删除歌曲并重新输出playlists.at(index).GetSongList()的内容时,歌曲不会被删除。我认为原因是调用GetSongList()不会检索实际的歌曲矢量,而只是返回一个副本,因此我不会改变原始矢量。如何直接从原始歌曲中删除歌曲?

3 个答案:

答案 0 :(得分:2)

使用成员函数remove_playlist从播放列表中删除歌曲。建议使用std :: list(代替vector),因为播放列表中需要经常删除,移动和插入。还可以使用智能指针来避免像std::list<std::shared_ptr<Song>>

这样的内存泄漏
void Playlist::remove_playlist(int index)
{
  if( index < songs.size() )
   {
    auto v = songs.at(index);
    songs.erase(std::remove(songs.begin(), songs.end(), v), songs.end());
   }
}

答案 1 :(得分:1)

你是对的,问题是由于复制副本造成的。

您可以返回指针

vector<Song*>* Playlist::GetSongList() {
    return &songs;
}

或参考

vector<Song*>& Playlist::GetSongList() {
    return songs;
}

到您的播放列表。

指针在可能发生时是可取的,没有可用的歌曲列表,因此有时您必须返回nullptr。所以不在您的示例中,因为成员播放列表始终可用。

在大多数其他情况下,返回引用是可取的。请注意,该方法未标记为const,因为对返回的vector<Song*>&的访问会更改Playlist实例。

另一种技术是根本不返回成员,而是使用委托来更改成员。

void Playlist::ChangeSongList( const std::function<void(vector<Song*>&)>& fn ) {
    fn(songs);
}

这样做的好处是,提供成员的类可以在线程环境中锁定对成员的访问,并在成员更改时更好地通知(例如,出于调试目的 - ChangeSongList可以在调用{之前和之后转储内容} {1}})

无论如何,返回副本通常也会出现性能问题,因此通常不会优先考虑。如果要返回const成员,则应使用const引用:

fn()

请注意,seccpur给出的答案是日常生活中最受欢迎的选择 - 课程应该并且通常会照顾其成员本身,并且不要让一些外部代码处理它。但是这个答案并没有描述返回副本,指针和引用的区别。

答案 2 :(得分:0)

  

引用

 Playlist* desiredPlaylist = playlists.at(index);
  vector<Song*> temporarySongList = desiredPlaylist->GetSongList();
  cout << "Pick a song index number to delete: ";
  cin >> index;
  temporarySongList.erase(tempSongList.begin() + index);
  

您正在通过执行此操作创建副本

vector<Song*> temporarySongList = desiredPlaylist->GetSongList();

所以你要从你的本地副本中删除。

考虑改变

vector<Song*> GetSongList() const { return songs };

vector<Song*>& GetSongList() { return songs } ;