关于vector指针传递数据的问题,如何解决?

我想写一个音乐播放器,我在main函数里创建了一个vector 的_song,并通过system_songs()函数进行了赋值,按照逻辑来说,我初始化player时,执行Player player(&_songs),这时player的list已经被赋值了,但运行的结果如图,没有达到我想再输出一遍歌单的效果,请问该如何修改?


#include<iostream>
#include<string>
#include<vector>
using namespace std;

class Album;
class Singer;

class Song    //歌曲类
{
public:
    string name;    //歌名
    Album* album;    //专辑
    Singer* singer;    //演唱者
    Song(string name, Singer* singer, Album* album)
    {
        this->name = name;
        this->album = album;
        this->singer = singer;
    }
    void viewSingerProfile();    //查看歌手资料
    void viewAlbumProfile();    //查看专辑资料
};


class Album    //专辑类
{
public:
    string name;    //专辑名
    Singer* singer;    //演唱者
    Album(string name, Singer* singer)
    {
        this->name = name;
        this->singer = singer;
    }
};


class Singer    //歌手类
{
public:
    string name;    //姓名
    vector<string>songs;    //所有歌曲名
    Singer(string name)
    {
        this->name = name;
    }
};
void Song::viewAlbumProfile()
{
    cout << "专辑名:" << this->album->name << endl;
}
void Song::viewSingerProfile()
{
    cout << "歌手名:" << this->singer->name << endl;
}


class Player    //播放器类
{
public:
    vector<Song>* list;    //播放列表
    Player(vector<Song>* list)
    {
        this->list = list;
    }
    int mode;    //播放模式
    void showList();    //显示播放列表
    void chooseOperation();    //提示选择操作
    void manageSongs();    //管理歌曲
    void add();    //添加歌曲
    void _delete();    //删除歌曲
    void play();    //播放
    void pause();    //暂停
    void previous();    //上一曲
    void next();    //下一曲
    void chooseMode();    //提示选择播放模式
    void viewSongProfile();    //查看歌曲详情
    void displayResults();    //反馈操作结果
};
void Player::chooseMode()
{

}
void Player::chooseOperation()
{

}
void Player::displayResults()
{

}
void Player::manageSongs()
{

}
void Player::add()
{

}
void Player::next()
{

}
void Player::pause()
{

}
void Player::play()
{

}
void Player::previous()
{

}
void Player::showList()
{
    for (int i = 0; i < 10; i++)
    {
        cout << i + 1 << "." << "歌名:" << (*list)[i].name << "\t" << "歌手:" << (*list)[i].singer->name << "\t" << "专辑:" << (*list)[i].album->name << endl;
    }
}
void Player::viewSongProfile()
{

}
void Player::_delete()
{

}


class User    //用户类
{
public:
    int operation;    //操作
    void sendOperation(int Operation);    //发送请求
};

void shuanghengxian()
{
    cout << "========================================================================================" << endl;
}

void bolangxian()
{
    cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
}

void _Operation()    //操作函数
{
    cout << "1.管理歌曲" << endl << "2.播放歌曲" << endl << "3.查看歌曲" << endl;
    shuanghengxian();
}

void system_songs(vector<Song>* _songs)
{
    Singer singer1("薛之谦");
    //singer1.songs.push_back("怪咖");    此处可添加歌手具体信息,对于此播放器操作功能有限,可不实现
    Album album1("沉默羔羊", &singer1);
    Song song1("演员", &singer1, &album1);
    (*_songs).push_back(song1);
    Singer singer2("伍佰");
    Album album2("几时回忆", &singer2);
    Song song2("突然的自我", &singer2, &album2);
    (*_songs).push_back(song2);
    Singer singer3("陈一发儿");
    Album album3("电竞贾玲", &singer3);
    Song song3("童话镇", &singer3, &album3);
    (*_songs).push_back(song3);
    Singer singer4("李荣浩");
    Album album4("小眼帅哥", &singer4);
    Song song4("作曲家", &singer4, &album4);
    (*_songs).push_back(song4);
    Singer singer5("邓紫棋");
    Album album5("腿长一米五", &singer5);
    Song song5("喜欢你", &singer5, &album5);
    (*_songs).push_back(song5);
    Singer singer6("周杰伦");
    Album album6("Jay", &singer6);
    Song song6("简单爱", &singer6, &album6);
    (*_songs).push_back(song6);
    Singer singer7("Beyond");
    Album album7("超越", &singer7);
    Song song7("光辉岁月", &singer7, &album7);
    (*_songs).push_back(song7);
    Singer singer8("陈奕迅");
    Album album8("我叫eason", &singer8);
    Song song8("十年", &singer8, &album8);
    (*_songs).push_back(song8);
    Singer singer9("张国荣");
    Album album9("峥嵘岁月", &singer9);
    Song song9("当爱已成往事", &singer9, &album9);
    (*_songs).push_back(song9);
    Singer singer10("许嵩");
    Album album10("年少回忆", &singer10);
    Song song10("南山忆", &singer10, &album10);
    (*_songs).push_back(song10);
    for (int i = 0; i < 10; i++)
    {
        cout << i + 1 << "." << "歌名:" << (*_songs)[i].name << "\t" << "歌手:" << (*_songs)[i].singer->name << "\t" << "专辑:" << (*_songs)[i].album->name << endl;
    }
}


int main(void)
{
    bolangxian();
    cout << "欢迎使用控制台音乐播放器" << endl;
    bolangxian();
    vector<Song>_songs;
    system_songs(&_songs);
    shuanghengxian();
    cout << "已展示当前所有歌曲,请选择您的操作:" << endl;
    _Operation();
    Player player(&_songs);
    player.showList();
}

img

img

不要传局部变量,这些都是栈内存,离开函数作用域就消失了,new 出来,使用堆内存。
如下方式修改

void system_songs(vector<Song> & _songs) // 这里改成引用
{
    Singer* singer1 = new Singer("薛之谦"); // 改成new
    //singer1.songs.push_back("怪咖");    此处可添加歌手具体信息,对于此播放器操作功能有限,可不实现
    Album album1 = new Album("沉默羔羊", singer1); // 去掉 &
    Song song1("演员", singer1, album1); // 去掉&
    _songs.push_back(song1);

该回答引用ChatGPT4与博主@晓码自在合作编写:

这里的问题是,Player类的构造函数Player(vector* list) 在初始化Player对象player时,只是将list指针赋值给player.list,并没有立即调用showList()方法显示播放列表。

所以,当你在main函数中执行player.showList()时,才真正显示播放列表。此时,player对象已经初始化完毕,所以不会再重新显示播放列表。

解决的办法有两种:

  1. 在Player类的构造函数中直接调用showList(),显示播放列表:
c++
Player(vector<Song>* list) 
{ 
    this->list = list;
    showList();  // 构造函数中直接显示播放列表
}

这样,在初始化Player对象player时,就已经显示了播放列表,所以后续调用player.showList()不会再显示。

  1. 在main函数中,先调用system_songs(&_songs)显示播放列表,然后再初始化Player对象:
c++
int main(void)
{
    // ...
    system_songs(&_songs);   // 首先显示播放列表
    shuanghengxian();     
    Player player(&_songs);  // 然后初始化Player对象
    player.showList();      // 此时不会再显示播放列表
} 

因为在初始化Player对象前,已经显示过播放列表,所以player.showList()不会再显示。

总结:如果你想在初始化某个类的对象时显示或输出某些内容,可以考虑在构造函数中直接显示,或者在初始化对象前先显示所需内容。否则,初始化对象后再显示,由于对象已经初始化完毕,不会重新显示相同内容。

还是不行哎