Search code examples
c++liststlcopy-constructorpush-back

I cant modify any private fields through public methods from class Artist. I tried adding reference( &) before function names but crashes


addAlbum should add Albums to a certain artist but push_back() doesnt work. as you can see in the picture i cannot modify any private field from Artist class through public methods https://i.sstatic.net/Imwf2.png Is this because i didnt write a proper copy constructor?

#include<iostream>
#include<list>
#include<string>
#include<fstream>

using namespace std;

class Person{
public:
    virtual string getName()=0;
    virtual string getCountry()=0;
    virtual list<pair<string,int> > getAlbumYear()=0;
    virtual list<pair<string,int> > getSongTrack()=0;
    virtual void show(ostream &out)=0;
    friend ostream &operator<<(ostream &out,Person &x){
        x.show(out);
        return out;
    }
    virtual void show(int i=0)=0;
    virtual ~Person(){}
};
class Artist:public Person{
    string Name;
    string Country;
    list<pair<string,int>> AlbumYear;
    list<pair<string,int>> SongTrack;
public:

    Artist(){}
    Artist::Artist(list<pair<string,int>> songtrack, list<pair<string,int>> albumyear, string country, string name):
    Name(name),Country(country),AlbumYear(albumyear),SongTrack(songtrack){}
    virtual ~Artist(){}
    string getName()override{
        return this->Name;
    }
    string getCountry()override{
        return this->Country;
    }
    list<pair<string,int>> getAlbumYear()override{
        return this->AlbumYear;
    }
    list<pair<string,int>> getSongTrack()override{
        return this->SongTrack;
    }
    void show(ostream &out)override{
        list<pair<string,int>>::iterator j=this->SongTrack.begin();
        for(list<pair<string,int>>::iterator i=this->AlbumYear.begin();i!=this->AlbumYear.end();i++,j++){
            cout<<i->first<<" , "<<i->second<<endl;
            while(j->first!=" " || j==this->SongTrack.end()){
                cout<<j->second<<" , "<<j->first<<endl;
                j++;
            }
        }       
    }
    void show(int i=0)override{
        if(i){
            for(list<pair<string,int>>::iterator i=this->AlbumYear.begin();i!=this->AlbumYear.end();i++)
                cout<<i->first<<endl;
            cout<<endl;
            return;
        }
        for(list<pair<string,int>>::iterator i=this->SongTrack.begin();i!=this->SongTrack.end();i++)
            if(i->first!=" ")
                cout<<i->first<<endl;
            else cout<<endl;
        cout<<endl;
    }



};

class Interface{
public:
    virtual void addPerson()=0;
    virtual void showAll()=0;
    virtual void addAlbum()=0;
    virtual void displayAlbums()=0;
    virtual void displaySongs()=0;
    virtual void displayDiscography()=0;
};

class Read:public Interface{
    list<Person*> person;

    string name(){
        string name;
        cout<<"Insert the name of the artist\n";
        cin>>name;
        cin.ignore();
        return name;
    }
    string country(){
        string country;
        cout<<"Insert country\n";
        cin>>country;
        cin.ignore();
        return country;
    }
    list<pair<string,int>> albumyear(){
        cout<<"Insert artist's album\n";
        list<pair<string,int>> albumyear;
        string a;
        getline(cin,a);
        int year;
        cout<<"Insert album's year\n";
        cin>>year;
        cin.ignore();
        albumyear.push_back(make_pair(a,year));
        return albumyear;
    }
    list<pair<string,int>> songtrack(){
        cout<<"Insert the number of songs the album contains\n";
        int n;
        cin>>n;
        cin.ignore();
        list<pair<string,int>> songtrack;
        cout<<"Insert the songs and tracks\n";
        string a;
        int b;
        for(int i=0;i<n;i++){   
            getline(cin,a);
            cin>>b;
            cin.ignore();
            songtrack.push_back(make_pair(a,b));
        }
        songtrack.push_back(make_pair(" ",1));
        return songtrack;

    }
    public:
        Read(){}
    void addPerson()override{
        this->person.push_back(new Artist(songtrack(),albumyear(),country(),name()));
    }
    void showAll()override{
        for(list<Person*>::iterator i=this->person.begin();i!=this->person.end();i++){
            cout<<(*i)->getName()<<", "<<(*i)->getCountry()<<endl;
            cout<<**i;
        }
    }
    void addAlbum()override{

        person.back()->getAlbumYear().back().first="asdasd";//doesnt work 
        cout<<"Insert artist's name\n";
        string name;
        getline(cin,name);
        for(list<Person*>::iterator i=person.begin();i!=person.end();i++){
            if(name.compare((*i)->getName())==0){
                cout<<"Insert album's name and year\n";
                string b;
                int c;
                getline(cin,b);
                cin>>c;
                (*i)->getAlbumYear().push_back(make_pair(b,c));
                cout<<"Insert the number of songs the album contains\n";
                int n;
                cin>>n;
                cin.ignore();
                cout<<"Insert song's name and track\n";
                for(int j=0;j<n;j++){
                    getline(cin,b);
                    cin>>c;
                    cin.ignore();
                    (*i)->getSongTrack().push_back(make_pair(b,c));
                    //cout<<(*i)->getSongTrack().back().first; shows nothing
                }
                (*i)->getSongTrack().push_back(make_pair(" ",1));
            }   
        }
    }





};

int main(){


    Interface *k=new Read();
    k->addPerson();
    k->addAlbum();
    k->showAll();
    system("pause");
    return 0; 
}

Thank you for your time!


Solution

  • virtual list<pair<string,int> > getAlbumYear()=0;
    virtual list<pair<string,int> > getSongTrack()=0;
    

    Your get-functions return by value, which means that you get a copy of the lists each time. Adding to a copy of course doesn't affect the original.