如何使用类成员搜索对象指针向量?

Posted

技术标签:

【中文标题】如何使用类成员搜索对象指针向量?【英文标题】:how to search through a vector of object pointers with a member of the class? 【发布时间】:2018-04-06 18:25:35 【问题描述】:

所以我想为一个班级找出这个程序,我需要模拟一个播放列表,可以在音乐库中添加和删除歌曲,在播放列表中添加和删除歌曲等。

我有一个 Song 类和一个 Playlist 类、一个向量库(用于歌曲库)和一个包含向量 songList 的向量播放列表。如果我想从库中删除一首歌曲并在库向量中获得歌曲指针的索引,我将如何检查该“歌曲”是否在任何“播放列表”中?这是我拥有的相关代码部分:

    using namespace std;

    class Song 
    public:
         Song(string title, string line, int count) 
              name = title;
              firstLine = line;
              playCount = count;
         
         string GetName() 
              return name;
         

         string GetFirstLine() 
              return firstLine;
         
    private:
         string name;
         string firstLine;
         int playCount;;
    ;

    class Playlist 
    public:
         Playlist(string name = "none")
              pName = name;
         
         void AddSong(Song* song) 
              songPtr.push_back(song);
         
         void RemoveSong(int songIndex) 
              songPtr.erase(songPtr.begin() + songIndex);
         
         string GetSongAtIndex(int index) 
              return (songPtr.at(index))->GetName();
         

    private:
         string pName;
         vector<Song*> songPtr;
    ;

    int main() 
    string userIn;
    vector<Song*> library;
    vector<Playlist> playlists;

    // code for adding songs to library using "new"
    // code for adding songs to playlist using "new"


    // delete song from library
    // first, list songs in library
        size = library.size();
        for (i = 0; i < size; i++) 
            cout << "  " << i << ": " << (library.at(i))->GetName();
            cout << endl;
        
        // have user pick wich song they want erased
        cout << "Pick a song index number: ";
        cin.clear();
        cin >> sIndex;

        // FIXME: check if song is in any playlist, and if it is, remove it
        string songName = (library.at(sIndex))->GetName();
        int size = playlists.size(); //remove song from playlists
        for (i = 0; i < size; i++) 
            int size2 = (playlists.at(i)).GetPSize();
            for (j = 0; j < size2; j++) 
                string tempName = (playlists.at(j)).GetSongAtIndex(j);
                if (tempName == songName) 
                    (playlists.at(i)).RemoveSong(j);
                
            
        
        // code to delete song from library and free the memory

我所拥有的东西不起作用,当我在删除后尝试列出库中的歌曲时,它给了我一个“超出范围”的错误并导致程序崩溃。当我注释掉有关在播放列表中查找它的部分时,它会从库中删除就好了。只有当我尝试检查该歌曲是否在播放列表中时才会出现错误。我对编程比较陌生,所以我可能只是遗漏了一些东西,但我不知道如何解决这个问题。

【问题讨论】:

请阅读minimal reproducible example和ericlippert.com/2014/03/05/how-to-debug-small-programs。 您需要使用vector&lt;Song&gt; songPtr;vector&lt;unique_ptr&lt;Song&gt;&gt; songPtr; 而不是vector&lt;Song*&gt; songPtr;。将指针存储在向量中不是一个好主意,您会遇到内存泄漏。例如,songPtr.erase(songPtr.begin() + songIndex); 泄漏 RAM。 实际问题可以使用std::find_if() 而且你的缩进不好。如果你不修复它,很少有人会在这里阅读你的代码。 【参考方案1】:

如果您从播放列表中删除一个元素,则不应增加索引并应减小大小:

// check if song is in any playlist, and if it is, remove it
string songName = library.at(sIndex)->GetName();
int size = playlists.size(); //remove song from playlists
for (j = 0; j < size2; )                 // do not increment j here
    string tempName = playlists.at(i).GetSongAtIndex(j); // i, not j for playlists.at()
    if (tempName == songName) 
        playlists.at(i).RemoveSong(j);  // j remains the same
        --size2;                          // one element less
     else 
        ++j;                              // increment here
    

【讨论】:

以上是关于如何使用类成员搜索对象指针向量?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用智能指针跟踪类的对象?

如何使 const 适用于作为共享指针的 C++ 类成员

如何重建包含向量的非指针类成员?

从类指针向量创建成员变量向量

用向量 c++ 中的指针成员初始化对象

如何使用 void 指针而不是对象访问类的成员变量