Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

przeniesienie obiektu do innej metody

Ostatnio zmodyfikowano 2016-09-05 14:33
Autor Wiadomość
hunter44
Temat założony przez niniejszego użytkownika
» 2016-09-03 16:37:46
Nie rozumiem tego całkowicie. Po co to mi jest potrzebne ? Wszystkie dane ze struktury idą tak jakby do jednego, zaprzyjaźnionego strumienia, ale dlaczego akurat to jest potrzebne ?
C/C++
friend istream & operator >>( istream & is, Player & player ) {
    is >> player.name >> player.surname >> player.age >> player.positionOnThePitch;
    return is;
}


Chcę w swoim programie użyć listy (std:list). Czy poniższy komparator w przypadku listy jest mi potrzebny ?
C/C++
class ComparePlayers {
public:
    bool operator ()( const Player & left, const Player & right ) {
        return left.surname < right.surname;
    }
};
P-151393
carlosmay
» 2016-09-03 17:12:47
Chcę w swoim programie użyć listy (std:list). Czy poniższy komparator w przypadku listy jest mi potrzebny ?
std::list<>

Nie rozumiem tego całkowicie. Po co to mi jest potrzebne ?
Bo wtedy używasz dla obiektów operatora strumienia, jak dla zwykłych zmiennych
i nie narusza to zasady SRP
P-151395
hunter44
Temat założony przez niniejszego użytkownika
» 2016-09-04 09:19:13
Posłuchałem się Ciebie i zacząłem pisać tak jak radisz. I teraz mam 3 sprawy:
1. Błąd w konstruktorze:  c2275: 'Gracz' illegal use of this type as an expression

2. Robię program z wykorzystaniem listy. Nie wiem do jakiej funkcji wsadzić dodanie gracza do listy, bo tu gdzie jest teraz raczej nie powinno być.

3. Chcę zrobić funkcję, która wyświetli całą listę. W funkcji tej też muszę użyć friend ostream ?
C/C++
#include <iostream>
#include <string>
#include <list>

using namespace std;

struct Gracz { // struktura przechowuje dane piłkarza, oraz ma zdefiniowaną funkcję wypełniającą pola struktury
    string imie;
    string nazwisko;
    int wiek;
    string pozycja;
   
    friend istream & operator >>( istream & is, Gracz & Gracz ) {
        is >> Gracz.imie >> Gracz.nazwisko >> Gracz.wiek >> Gracz.pozycja;
        return is;
    }
};

// w klasie, jako atrybut jest kontener std::set, dzięki deklaracji kontenera w klasie
// a nie w metodzie, kontener jest znany we wszystkich metodach i funkcjach zaprzyjaźnionych z klasą
class Druzyna {
    list < Gracz > team;
    string imie;
    string nazwisko;
    int wiek;
    string pozycja;
public:
   
   
    Druzyna::Druzyna( string = "Jan", string = "kowalski", int = 20, string = "Napastnik" ) // konstruktor.
    {
        string a, b, d;
        int c;
        imie = a;
        nazwisko = b;
        wiek = c;
        pozycja = d;
    }
   
   
   
   
    void dodaj_gracza() {
        Gracz Gracz; // lokalna deklaracja obiektu
        cin >> Gracz; // użycie przeciążonego operator>> ze struktury (wypełnia pola struktury)
       
    }
   
    friend ostream & operator <<( ostream & os, const Druzyna & Druzyna ) {
        for( auto const & elem: Druzyna.team ) {
            os << elem.imie << ' ' << elem.nazwisko << "\nwiek "
            << elem.wiek << "\npozycja" << elem.pozycja << '\n';
           
        }
        return os;
        list < Gracz > lista;
        lista.push_back( Gracz );
    }
   
   
};

int main()
{
    Druzyna druzyna; // deklaracja obiektu klasy (z kontenerem)
    druzyna.dodaj_gracza();
    cout << druzyna << '\n'; // użycie przeciążonego operator>> z klasy, wypisuje w pętli zawartość kontenera
   
    system( "PAUSE" );
}
P-151411
carlosmay
» 2016-09-04 09:51:45
C/C++
#include <iostream>
#include <string>
#include <list>

using namespace std;

struct Gracz { // struktura przechowuje dane piłkarza, oraz ma zdefiniowaną funkcję wypełniającą pola struktury
    string imie;
    string nazwisko;
    int wiek;
    string pozycja;
   
    friend istream & operator >>( istream & is, Gracz & Gracz ) {
        is >> Gracz.imie >> Gracz.nazwisko >> Gracz.wiek >> Gracz.pozycja;
        return is;
    }
};

// w klasie, jako atrybut jest kontener std::set, dzięki deklaracji kontenera w klasie
// a nie w metodzie, kontener jest znany we wszystkich metodach i funkcjach zaprzyjaźnionych z klasą
class Druzyna {
    list < Gracz > team;
public:
    // w takich prostych przypadkach mozesz korzystać z konstruktrów, które produkuje kompilator
    Druzyna() { }
    Druzyna( initializer_list < Gracz > gracze )
        : team( gracze )
    { }
    Druzyna( const Druzyna & druzyna )
        : team
    { druzyna.team }
    { }
    ~Druzyna() { }
    Druzyna & operator =( const Druzyna & druzyna ) {
        team = druzyna.team;
        return * this;
    }
   
    void dodaj_gracza() {
        Gracz gracz; // lokalna deklaracja obiektu
        cin >> gracz; // użycie przeciążonego operator>> ze struktury (wypełnia pola struktury)
        team.push_back( gracz );
    }
   
    friend ostream & operator <<( ostream & os, const Druzyna & Druzyna ) {
        for( auto const & elem: Druzyna.team ) {
            os << elem.imie << ' ' << elem.nazwisko << "\nwiek "
            << elem.wiek << "\npozycja" << elem.pozycja << '\n';
           
        }
        return os;
    }
   
   
};

int main()
{
    Druzyna druzyna { }; // deklaracja obiektu klasy (z kontenerem)
    druzyna.dodaj_gracza();
    cout << druzyna << '\n'; // użycie przeciążonego operator>> z klasy, wypisuje w pętli zawartość kontenera
    Druzyna drugaDruzyna = druzyna;
    cout << drugaDruzyna << '\n';
    Gracz gracz;
    cin >> gracz;
    Druzyna trzeciaDruzyna( { gracz } );
    cout << trzeciaDruzyna << '\n';
}

Identyfikatory zmiennych nie powinny być identyczne jak ich typy, tj.
C/C++
Gracz Gracz; // źle

edit: poprawiłem kod do zasady rule of three.
system( "pause" );
 pewnie jest niepotrzebny. Większość środowisk samo potrafi zatrzymać program przed zamknięciem.
Jeśli nie skorzystaj czegoś lżejszego, np.
cin.get();
.
P-151412
hunter44
Temat założony przez niniejszego użytkownika
» 2016-09-04 17:30:33
Ilekroć uwierzę w siebie i chcę coś sam zrobić, tylekroć brutalnie spadam na twarz.
Zmodyfikowałem dalej kod. Tym razem chciałem wykonać pętlę, która będzie wyświetlała wszystkich wprowadzonych piłkarzy, ponieważ dotychczasowy kod wyświetlał tylko jednego, od razu po jego wprowadzeniu. Znalazłem wzór jak taka pętla powinna wyglądać, ale znowu coś skopałem przy jej tworzeniu. I dodatkowo dodałem menu do programu.
Pętla o z którą mam problem znajduje się w
void wyswietl_liste
.
C/C++
Error C2679 binary '<<': no operator found which takes a right - hand operand of type 'const Gracz'( or there is no acceptable conversion )

C/C++
#include <iostream>
#include <string>
#include <list>

using namespace std;

struct Gracz { // struktura przechowuje dane piłkarza, oraz ma zdefiniowaną funkcję wypełniającą pola struktury
    string imie;
    string nazwisko;
    int wiek;
    string pozycja;
   
    //wzór:  friend ostream & operator<<(ostream & os, OwnObject & oo);
   
    friend istream & operator >>( istream & is, Gracz & Gracz ) {
       
        cout << "\n\nImie: "; is >> Gracz.imie;
        cout << "Nazwisko: "; is >> Gracz.nazwisko;
        cout << "Wiek: "; is >> Gracz.wiek;
        cout << "Pozycja:"; is >> Gracz.pozycja; cout << "\n\n";
        return is;
    }
};

// w klasie, jako atrybut jest kontener std::set, dzięki deklaracji kontenera w klasie
// a nie w metodzie, kontener jest znany we wszystkich metodach i funkcjach zaprzyjaźnionych z klasą
class Druzyna {
    list < Gracz > team;
public:
    // w takich prostych przypadkach mozesz korzystać z konstruktrów, które produkuje kompilator
    Druzyna() { }
    Druzyna( initializer_list < Gracz > gracze )
        : team( gracze )
    { }
    Druzyna( const Druzyna & druzyna )
        : team
    { druzyna.team }
    { }
    ~Druzyna() { }
    Druzyna & operator =( const Druzyna & druzyna ) {
        team = druzyna.team;
    }
   
    void dodaj_gracza() {
        Gracz gracz; // lokalna deklaracja obiektu
        cin >> gracz; // użycie przeciążonego operator>> ze struktury (wypełnia pola struktury)
        team.push_back( gracz );
    }
   
    friend ostream & operator <<( ostream & os, const Druzyna & Druzyna ) {
        for( auto const & elem: Druzyna.team ) {
            os << elem.imie << ' ' << elem.nazwisko << ", " << "lat: "
            << elem.wiek << ", " << elem.pozycja << '\n';
           
        }
        return os;
    }
   
    void wyswietl_liste()
    {
       
       
        for( list < Gracz >::const_iterator iterator = team.begin(), end = team.end(); iterator != end; ++iterator ) {
            cout << * iterator;
        }
       
    }
};



int main()
{
    int temp;
    do {
        cout << "1. Dodaj pilkarza" << endl;
        cout << "2. wyswietl liste pilkarzy" << endl;
        cout << "3. Zapisz do pliku" << endl;
        cout << "4. Wczytaj z pliku" << endl;
        cout << "5.Zakoncz\n" << endl;
       
        cin >> temp;
       
        switch( temp )
        {
        case 1:
            { //dodaj pilkarza
                Druzyna druzyna { }; // deklaracja obiektu klasy (z kontenerem)
                druzyna.dodaj_gracza();
               
            }
            continue;
        case 2: //wyswietl liste
            {
                cout << "\nLista pilkarzy:\n" << endl;
                Druzyna druzyna { };
                druzyna.wyswietl_liste();
               
                continue;
            }
            default:
            cout << "\nNiepoprawne polecenie. Podaj cyfre z zakresu od 1 do 5\n";
            continue;
        }
    } while( temp != 5 );
   
   
   
}

EDIT: W sumie funkcja ktora ma wyswietlac jest jako void, więc może to jest problemem, no bo jak funkcja, która ma coś zwrócić może być voidem ? Tyko teraz nie wiem jaki parametr wpisać.
P-151432
karambaHZP
» 2016-09-04 19:01:41
Mając przeładowany
operator <<
 nie potrzebujesz metody
wyswietl_liste
. Najwyraźniej nie rozumiesz tego mechanizmu. Dodajesz jednego gracza to wyświetla jednego gracza.
switch
 jest kiepsko rozwiązany. Jeszcze to nieszczęsne
continue
, po co?
P-151435
hunter44
Temat założony przez niniejszego użytkownika
» 2016-09-04 19:18:27
Na prawdę czytałem o przeciążeniu operatora. Jak widać nie do końca zrozumiałem. Odkryłem cos. Już chyba częściowo rozumiem. Przeciążając operator, wszystko do niego idzie.
Gdy zrobiłem:
C/C++
druzyna.dodaj_gracza();
druzyna.dodaj_gracza();
druzyna.dodaj_gracza();
cout << druzyna << '\n';

To wyswietlilo mi wszystkich 3 graczy bo właśnie tyle ich dodałem, więc nie jest mi potrzebna pętla do wyświetlania graczy. Już rozumiem, że wszystko i tak ląduje do "druzyna".

Tylko teraz znowu mam problem. Tak jak napisałeś: dodaje jednego gracza to wyświetla jednego gracza. To jak dodać n graczy ? No bo bezsensem jest za każdym razem dopisywać do kodu
C/C++
druzyna.dodaj_gracza();
Na razie mechanizm działa tak, że jak dodam jednego piłkarza i potem znowu to zrobię to dane są nadpisywane. I dodając drugiego piłkarza, tracę z listy pierwszego.
Chcialem po dodaniu piłkarza zwiększać listę o jeden, ale tak tego problemu nie rozwiążę.
C/C++
int licznik = 1;
licznik = licznik + 1;
team.resize( licznik );

P-151436
carlosmay
» 2016-09-04 20:14:08
Myślę, że teraz masz już gotowy program.
C/C++
int main()
{
    Druzyna druzyna { }; // deklaracja obiektu klasy (z kontenerem)
   
    char switchOpcja { }; // 0 - wyjdz, 1 - dodaj jednego gracza, 2 - dodaj n graczy, 3 - pokaz druzyne
    do {
        cin >> switchOpcja;
        switch( switchOpcja ) {
        case '1':
            druzyna.dodaj_gracza();
            break;
        case '2': {
                size_t nLoops { };
                cin >> nLoops;
                for( size_t i = 0; i < nLoops; ++i ) {
                    druzyna.dodaj_gracza();
                }
            }
            break;
        case '3':
            cout << druzyna << '\n';
            break;
        case '0':
            cout << "Koniec.\n";
            break;
        default:
            cerr << "Jakis nieokreslony przypadek.\n";
        }
    } while( switchOpcja != '0' );
   
}
Dodawanie kolejnych funkcjonalności nie będzie problemem.
P-151437
1 « 2 » 3
Poprzednia strona Strona 2 z 3 Następna strona