Problemik z zadaniem C++ stephen prata

0

Witam mam problem z zad.1 z rozdzialu 14 z ksiazki szkola programownia C++. Poniżej zamiesczam kod:

Plika naglowkowy:

 
#ifndef WINEC_H_
#define WINEC_H_
#include <valarray>
#include <iostream>
#include <string>
#include <cstring>
template <class Tl, class T2>
class Pair
{
private:
    Tl Year;
    T2 Bottles;
public:
    Tl & first () ;
    T2 & second();
    Tl first() const{return Year;}
    T2 second() const {return Bottles;}
    Pair(const Tl & aval, const T2 & bval) : Year (aval), Bottles(bval)
    {}
    Pair() {}
};
template<class Tl, class T2>
Tl & Pair<Tl, T2>::first()
{
    return Year;
}
template<class Tl, class T2>
T2 & Pair<Tl,T2>::second()
{
    return Bottles;
}
class Wine
{
private:
typedef std::valarray<int> ArrayInt;
typedef Pair<ArrayInt, ArrayInt> PairArray;
std::string label;
int count;
PairArray ilosc;
public:
Wine():ilosc()
{}
// Inicjalizuje skladowe label parametrem l, liczbe lat parametrem y,
// roczniki parametrem yr[], skladowe bottles parametrem bot[]
Wine(const char * l, int y, const int yr[], const int bot[]);
//Inicjalizuje skladowe label parametrem l. liczbe lat parametrem y,
// tworzy tablice obiektów o dlugosci y
Wine(const char * l, int y);
void GetBottles() const;
void Show() const;
std::string & Label() ;
};
Wine::Wine(const char * l, int y, const int yr[], const int bot[]):label(l),count(y),ilosc(ArrayInt(y),ArrayInt(y))
{
    for (int i=0;i<count;i++)
    {
    ilosc.first()[i]=yr[i];
    ilosc.second()[i]=bot[i];
    }
}
Wine::Wine(const char * l, int y):label(l),count(y)//,ilosc(ArrayInt(y),ArrayInt(y))
{}
void Wine::GetBottles() const
{
    using std::cout;
    using std::cin;
    cout<<"Podaj dane o winie"<<label<<"dla"<<count<<"rocznikow\n";
    for (int i=0;i<count;i++)
    {
    cout<<"Podaj rocznik ";
    cin>>ilosc.first()[i];
    cout<<"Podaj ilosc butelek ";
    cin>>ilosc.second()[i];
    }
}
void Wine::Show()const
{
    std::cout<<"Wino"<<label<<"\n";
    std::cout<<"Rocznik   Butelki\n";
    for (int i=0;i<count;i++)
    {
            std::cout<<ilosc.first()[i];
            std::cout<<"      ";
            std::cout<<ilosc.second()[i];
            std::cout<<"\n";
    }
}
std::string & Wine::Label()
{
    return label;
}

#endif


Program testowy:

 
#include <iostream>
#include "winec.h"
int main (void)
{
using std::cin;
using std::cout;
using std::endl;
cout << "Podaj nazwe wina: ";
char lab[50];
cin.getline (lab, 50);
cout << "Podaj liczbe roczników: ";
int yrs;
cin >> yrs;
Wine holding (lab, yrs) ; // Zapisuje nazwe, liczbe roczników i przekazuje
// informacje o tej liczbie do tablicy
holding.GetBottles () ; // Pobiera dane o roczniku i liczbie butelek
holding.Show () ; // Wyswietla zawartosc obiektu
const int YRS = 3;
int y[YRS] = { 1993, 1995, 1998 };
int b[YRS] = { 48, 60, 72 } ;
// Tworzy nowy obiekt, inicjalizuje za pomoca danych w tablicach y oraz b
Wine more("Gushing Grape Red", YRS, y, b ) ;
more.Show();
//cout << "Laczna liczba butelek wina " << more.Label();
// Uzywa metody Label!)
//<< ": " << more.sum() << endl;
// Uzywa metody sum()
cout << "Koniec\n";
return 0;
}

Mianowicie gdy program pobiera dane z klawiatury to w kolumnie wyswietla mi 0, natomiast gdy pobiera dane z tablicy wszystko dziala jak nalezy. Wytłumaczcie mi co robie nie tak, z góry dziękuje.

1

super, ale nie kazdy ma ksiazke. Podaj tresc

0

Klasa Wine posiada obiekt składowy typu string (patrz rozdział 4.). który przechowuje
nazwę wina. oraz obiekt typu Pair (opisany w tym rozdziale) zawierający obiekty typu
valarray <int> (także opisane w tym rozdziale). Pierwsza składowa każdego obiektu
Pair przechowuje rocznik wina, a druga składowa przechowuje liczbę posiadanych butelek
danego rocznika. Na przykład pierwszy obiekt valarray obiektu Pair może przechowywać
lata 1988, 1992 i 1996. a drugi obiekt valarray może przechowywać liczbę butelek
24, 48 i 144. Klasa Wine może też posiadać składową w postaci liczby całkowitej, która
przechowuje liczbę roczników. Do ułatwienia pisania kodu mogą Ci się przydać poniższe
definicje typu:

 
typedef std::valarray<int> Arraylnt;
typedef Pair<ArrayInt, Arraylnt> PairArray;

Dzięki temu nazwa PairArray reprezentuje typ Pair< std::valarray <int> ,
std::valarray<int>>. Zaimplementuj klasę Wine, używając mechanizmu zawierania.
Klasa powinna posiadać konstruktor domyślny oraz przynajmniej wymienione poniżej
konstruktory:

// Inicjalizuje składową label parametrem l, liczbę lat parametrem y,
// roczniki parametrem yr[], składową bottles parametrem bot[]
Wine (const char * l, int y, const int yr[], const int bot[]);
//Inicjalizuje składową label parametrem l. liczbę lat parametrem y,
// tworzy tablicę obiektów o długości y
Wine(const char * l, int y);
 

Klasa Wine powinna posiadać metodę GetBottles(), która przyjmuje obiekt Wine
o liczbie roczników równej y i prosi użytkownika o podanie odpowiednich roczników oraz
liczby butelek każdego rocznika. Metoda Label () powinna zwracać referencję do nazwy
wina. Metoda sum () ma zwracać łączną liczbę butelek w drugim obiekcie valarray<int>
obiektu Pair.

Oto całe polecenie.

2

Witam mam problem z zad.1 z rozdzialu 14 z ksiazki szkola programownia C++
Dzięki za podanie zadania, teraz każdy może sięgnąć do swojego egzemplarza i przeczytać zadanie...

Po pierwsze, popracuj nad formatowaniem swojego kodu, zobacz o ile czytelniejszy może on być: https://gist.github.com/KrzaQ/1269e4b9b5432f026a5e

    Tl & first () ;
    T2 & second();
    Tl first() const{return Year;}
    T2 second() const {return Bottles;}

Dlaczego zwracasz kopię dla const this? Dlaczego pierwszy typ nazywa się Tl, a nie T1? Ty to skanowałeś czy coś? Dlaczego w typie, który wydaje się być generycznym nazwy pól klasy to Year i Bottles? Jeśli już przy tym jesteśmy to dlaczego nie użyć po prostu std::pair? Widać przecież, że nie masz awersji do stosowania biblioteki standardowej gdzie indziej.

WTF. Kod funkcji ma sens, chociaż jest on niezgodny z nazwą - nazwa to jednoznaczny getter, a zwracasz void i pobierasz dane od użytkownika.

void GetBottles() const;

Ta funkcja, w powiązaniu z szablonem klasy Pair jest też przyczyną Twojego problemu: GetBottles wywołujesz na const this, więc wywołujesz przeładowania

Tl first() const{return Year;}
T2 second() const {return Bottles;}

Inaczej mówiąc dostajesz kopię wartości i do niej zapisujesz wejście od użytkownika. Oryginał jest niezmieniony.

2
...
Wine::Wine(const char * l, int y):label(l),count(y),ilosc(ArrayInt(y),ArrayInt(y)) // koniecznie zainicjalizować ilosc
{}
void Wine::GetBottles() // bez const
{
...
  1. nie używaj i++ tam gdzie możesz użyć ++i
  2. nie wyważaj otwartych drzwi, jak masz dostępną std::pair to nie pisz własnego Pair
0
kq napisał(a):
void GetBottles() const;

Ta funkcja, w powiązaniu z szablonem klasy Pair jest też przyczyną Twojego problemu: GetBottles wywołujesz na const this, więc wywołujesz przeładowania

Tl first() const{return Year;}
T2 second() const {return Bottles;}

Inaczej mówiąc dostajesz kopię wartości i do niej zapisujesz wejście od użytkownika. Oryginał jest niezmieniony.

A no tak! Nie zwróciłem uwagi na const w funkcji GetBottles();

_13th_Dragon napisał(a):

nie wyważaj otwartych drzwi, jak masz dostępną std::pair to nie pisz własnego Pair

W tresci zadania mialem uzyc wlasnego Pair nie ze standardowej biblioteki.

Tak czy siak dzieki wam program dziala jak nalezy. Zastosuje sie do waszych rad.

1 użytkowników online, w tym zalogowanych: 0, gości: 1