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

C++ 如何删除指针向量中属于指针对象的项,c++,pointers,C++,Pointers,我有一个playlist类,它包含一个歌曲指针向量 class Playlist { public: Playlist(); Playlist(string); vector<Song*> GetSongList() const; private: vector<Song*> songs; string name; }; 在我的主要方法中,我有一个播放列表指针向量:vector playlists 我想从特定播放列表中删除歌曲指针

我有一个playlist类,它包含一个歌曲指针向量

class Playlist {
public:
    Playlist();
    Playlist(string);
    vector<Song*> GetSongList() const;
private:
    vector<Song*> songs;
    string name;
};
在我的主要方法中,我有一个播放列表指针向量:
vector 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);
Playlist*desiredPlaylist=playlists.at(索引);
vector temporarySongList=desiredPlaylist->GetSongList();
cout>指数;
temporarySongList.erase(tempSongList.begin()+索引);
当我从矢量中删除歌曲并重新输出播放列表的内容时,
playlists.at(index).GetSongList()
歌曲不会被删除。我想原因是调用
GetSongList()
不会检索实际的歌曲向量,而是返回一个副本,因此我不会更改原始向量。我如何直接从原曲中删除歌曲

引述

Playlist*desiredPlaylist=playlists.at(索引);
vector temporarySongList=desiredPlaylist->GetSongList();
cout>指数;
temporarySongList.erase(tempSongList.begin()+索引);

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

vector<Song*> temporarySongList = desiredPlaylist->GetSongList();
vector temporarySongList=desiredPlaylist->GetSongList();
因此,您正在从本地副本中删除

考虑改变

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

vector&GetSongList(){返回歌曲};

你说得对,问题是因为返回了副本

您可以返回一个指针

vector<Song*>* Playlist::GetSongList() {
    return &songs;
}
这样做的好处是,提供成员的类可以在线程化环境中锁定对成员的访问,并且在成员被更改时可以得到更好的通知(例如,出于调试目的,ChangeSongList可以在调用
fn()
之前和之后转储内容)

无论如何,返回副本通常也会有性能问题,因此通常是不可取的。如果要返回常量成员,则应使用常量引用:

const vector<Song*>& Playlist::GetSongList() const {
    return songs;
}
常量向量和播放列表::GetSongList()常量{ 返回歌曲; }
请注意,seccpur给出的答案是日常生活中最受欢迎的选择——类应该而且通常会照顾自己的成员,不要让一些外部代码来处理它。但是这个答案并没有说明返回副本、指针和引用的区别。

使用成员函数remove\u playlist从播放列表中删除歌曲。建议使用std::list(代替vector),因为播放列表中需要频繁删除、移动和插入。还可以使用智能指针来避免像这样的内存泄漏
std::list

void Playlist::删除\u播放列表(int索引)
{
如果(索引
添加一个成员函数
Playlist::RemoveSong
,用于从矢量中删除歌曲?无关:检查为什么要存储指向歌曲的指针,并确保您熟悉存储指向对象的容器。如果
GetSongList
为常量,那么它返回的内容不能用于修改对象<代码>常量-通知返回类型。哎呀,我错过了。固定的!非常确定您可以将其简化为
songs.erase(songs.begin()+index)
通过测试确保
索引
在范围内。如果多个播放列表引用要删除的同一首歌曲如何?在列表中查找O(N)中的位置,因此无法立即确定列表是否比向量更好。对于多个容器实例持有指向同一项目实例的指针,
std::shared_ptr
是可取的。@codekaizer:std::shared_ptr是播放列表中多首歌曲的最佳选择。上面,只是一个伪代码来实现OP问题的第一手资料。那么如何从播放列表中删除一首歌曲呢。。。就像Ryan已经做的那样:
erase(songList.begin()+index)
。但是不要忘了在之前检查边界(或者使用
vector::at()
,它可以为您执行此操作,并结合
try/catch
)。不要忘记
删除
(或者更好地使用智能指针)添加&会给我一个新错误:“return”:无法从“const std::vector”转换为“std::vector”&“是的,我已经在回答中写下了原因:请注意,该方法未标记为
const
,因为对返回的
向量&
的访问会改变
播放列表
实例。“。您必须从方法声明中删除
const
,因为它实际上不再是
const
。Oops。。。但我忘记删除指针返回中的
常量,已修复。
vector<Song*>& GetSongList() { return songs } ;
vector<Song*>* Playlist::GetSongList() {
    return &songs;
}
vector<Song*>& Playlist::GetSongList() {
    return songs;
}
void Playlist::ChangeSongList( const std::function<void(vector<Song*>&)>& fn ) {
    fn(songs);
}
const vector<Song*>& Playlist::GetSongList() const {
    return songs;
}
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());
   }
}