• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dziedziczenie prywatne szablonu

Object Storage Arubacloud
0 głosów
554 wizyt
pytanie zadane 9 września 2017 w C i C++ przez B0nkers Początkujący (310 p.)

Witam,

Mam problem z zadaniem 2 z rozdziału 14, książki S. Prata "Język C++. Szkoła Programowania" .
Chodzi o dziedziczenie prywatne szablonu klasy.

Oto plik nagłówkowy i poniżej kod programu głównego.

#ifndef WINEC_H_
#define WINEC_H_
#include <iostream>
#include <valarray>
#include <string>
#include "stdafx.h"

template <class T1, class T2>
class Pair
{
protected:
	T1 Year;
	T2 Bottles;
public:
	T1 & first();
	T2 & second();
	T1 first() const 
	{
		return Year; 
	}
	T2 second() const
	{ 
		return Bottles; 
	}
	Pair(const T1 & aval, const T2 & bval) 
		: Year(aval), Bottles(bval) 
	{
	}
	Pair() {}
};

template <class T1, class T2>
T1 & Pair<T1, T2>::first()
{
	return Year;
}
template<class T1, class T2>
T2 & Pair<T1, T2>::second()
{
	return Bottles;
}

template <class T1, class T2>
class Wine : private Pair<T1, T2>
{
private:
	typedef std::valarray<int> ArrayInt;
	typedef Pair<ArrayInt, ArrayInt> PairArray;
	//PairArray <Pair::Year, Pair::Bottles>;
	std::string label;
	int count;
	//PairArray Amount;
public:

	template <class Pair>
	Wine()
		: PairArray()
	{
	}
	//inicjalizuje składową label parametrem l, liczbę lat parametrem y,
	//roczniki parametrem yr[], składową bottles parametrem bot[]

	//template <class Pair>
	Wine(const char * l, int y, const int yr[], const int bot[])
		: label(l), count(y), PairArray(ArrayInt(y),ArrayInt(y))
	{
		for (int i = 0; i < count; i++)
		{
			PairArray::first()[i] = yr[i];
			PairArray::second()[i] = bot[i];
		}
	}
	//inicjalizuje składową label parametrem l, liczbę lat parametrem y,
	//tworzy tablicę obiektów o długości y

	//template <class Pair>
	Wine(const char * l, int y)
		: label(l), count(y), PairArray(ArrayInt(y), ArrayInt(y))
	{
	}

	~Wine() {};
	//metody
	void GetBottles()
	{
		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 >> PairArray::first()[i];
			cout << "Podaj ilosc butelek: ";
			cin >> PairArray::second()[i];
		}
	}

	const std::string & Label() const
	{
		return label;
	}

	void Show() const
	{
		std::cout << "Wino \"" << label << "\"\n";
		std::cout.width(6);
		std::cout << "Rocznik   Butelki\n";
		for (int i = 0; i < count; i++)
		{
			std::cout.width(6);
			std::cout << PairArray::first()[i];
			std::cout.width(7);
			std::cout << PairArray::second()[i];
			std::cout << std::endl;
		}
	}

	int sum() const
	{
		int total = 0;
		for (int i = 0; i < count; i++)
			total += PairArray::second()[i];

		return total;
	}
};

#include "stdafx.h"
#include "winec02.h"

int main()
{
	using std::cin;
	using std::cout;
	using std::endl;

	cout << "Podaj nazwe wina: ";
	char lab[50];
	cin.getline(lab, 50);
	cout << "Podaj liczbe rocznikow: ";
	int yrs;
	cin >> yrs;

	Wine holding(lab, yrs);	//zapisuje nazwę, liczbę roczników i przekazuje informację o
							//tej liczbie do tablicy
	holding.GetBottles();	//pobiera dane o roczniku i liczbie butelek
	holding.Show();			//wyświetla zawartość obiektu

	const int YRS = 3;
	int y[YRS] = { 1993, 1995, 1998 };
	int b[YRS] = { 48, 60, 72 };
	//tworzy nowy obiekt, inicjalizuje za pomocą danych w tablicach y oraz b
	Wine more("Gushing Grape Red", YRS, y, b);
	//more.Show();
	//cout << "Laczna liczba butelek wina " << more.Label()	//używa metody Label()
	//	<< ": " << more.sum() << endl;	//używa metody sum()
	cout << "Koniec\n";


	system("PAUSE");
	return 0;
}

 

Proszę o pomoc w znalezieniu błędów smiley

 

komentarz 9 września 2017 przez criss Mędrzec (172,590 p.)
A na czym polega problem? (dlaczego trzeba o to pytać)
komentarz 9 września 2017 przez B0nkers Początkujący (310 p.)
przeniesione 10 września 2017 przez draghan
Polega na tym że nie wiem czy to do końca dobrze zrobiłem, kompilator wyświetla błędy w konkretyzacji
komentarz 10 września 2017 przez criss Mędrzec (172,590 p.)
A nie zamierzasz może podzielić się z nami tymi błędami? Ja nie rozumiem. Czy to nie jest oczywiste, że znajomość błędów pomaga w szukaniu problemów?

PS: następnym razem pisz w komentarzach, zamiast tworzyć nową odpowiedź

2 odpowiedzi

+1 głos
odpowiedź 10 września 2017 przez j23 Mędrzec (194,920 p.)
wybrane 10 września 2017 przez B0nkers
 
Najlepsza
Wine holding(lab, yrs);
...

Wine more("Gushing Grape Red", YRS, y, b);

Wine jest szablonem, a Ty tworzysz instancje tej klasy, jakby była zwykłą klasą. Podaj parametry szablonu przy tworzeniu:

using vaint_t = std::valarray<int>;

Wine<vaint_t, vaint_t> holding(lab, yrs);
 ... 

Wine<vaint_t, vaint_t> more("Gushing Grape Red", YRS, y, b);

albo dziedzicz tak:

using vaint_t = std::valarray<int>;

class Wine : private Pair<vaint_t, vaint_t> { ... }

 

komentarz 10 września 2017 przez B0nkers Początkujący (310 p.)

No dobra ale jak dam nic i usunę <vaint_t, vaint_t> przy Wine, to wtedy wyskakują błędy typu:

"more" niezadeklarowany identyfikator

 

komentarz 10 września 2017 przez B0nkers Początkujący (310 p.)
Dobra już wpadłem na to, wystarczyło tylko zasięg w metodach i konstruktorach dopisać
komentarz 10 września 2017 przez B0nkers Początkujący (310 p.)

A w pierwszej wersji to  template <class T1, class T2> musi być przed klasą?

komentarz 10 września 2017 przez j23 Mędrzec (194,920 p.)

Tu masz kod, który powinien skompilować się bez błędu/warninga:

template <class T1, class T2>
class Pair
{
protected:
    T1 Year;
    T2 Bottles;
public:
    T1 & first()  { return Year; }
    T2 & second() { return Bottles; }
    T1 first() const { return Year; }
    T2 second() const { return Bottles; }
    
	Pair(const T1 & aval, const T2 & bval) 
        : Year(aval), Bottles(bval) 
    {}

	Pair(T1 && aval, T2 && bval) 
        : Year(aval), Bottles(bval) 
    {}
	
    Pair() {}
};
 
 
using vaint_t = std::valarray<int>; 


class Wine : private Pair<vaint_t, vaint_t>
{
private:
    std::string label;
    int count;

public:

    Wine()
        : count(0)
    { }

    Wine(const char * l, int y, const int yr[], const int bot[])
        : Pair<vaint_t, vaint_t>(vaint_t(yr, y), vaint_t(bot, y)),
		label(l), 
		count(y)
		
    { }

    Wine(const char * l, int y)
        : Pair(vaint_t(y), vaint_t(y)),
		label(l), 
		count(y)		
    { }
 
    ~Wine() {};
    
    void GetBottles()
    {
        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 >> first()[i];
            cout << "Podaj ilosc butelek: ";
            cin >> second()[i];
        }
    }
 
    const std::string & Label() const
    {
        return label;
    }
 
    void Show() const
    {
        std::cout << "Wino \"" << label << "\"\n";
        std::cout.width(6);
        std::cout << "Rocznik   Butelki\n";
        for (int i = 0; i < count; i++)
        {
            std::cout.width(6);
            std::cout << first()[i];
            std::cout.width(7);
            std::cout << second()[i];
            std::cout << std::endl;
        }
    }
 
    int sum() const
    {
        int total = 0;
        for (int i = 0; i < count; i++)
            total += second()[i];
 
        return total;
    }
};

 

// przykładowo
const int YRS = 3;
int y[YRS] = { 1993, 1995, 1998 };
int b[YRS] = { 48, 60, 72 };

Wine more("Gushing Grape Red", YRS, y, b);

 

komentarz 10 września 2017 przez B0nkers Początkujący (310 p.)

Ok czyli z tego co widzę to zapomniałem tylko o jednej rzeczy,bo składowe Pair są chronione a nie prywatne i niepotrzebnie ten operator zasięgu wstawiałem w metodach smiley.  Wielkie dzięki! 

0 głosów
odpowiedź 10 września 2017 przez criss Mędrzec (172,590 p.)

Tutaj widzę jeden problem:

template <class T1, class T2>
class Wine : private Pair<T1, T2>
{
private:
    typedef std::valarray<int> ArrayInt;
    typedef Pair<ArrayInt, ArrayInt> PairArray;
    std::string label;
    int count;
public:
 
    template <class Pair>
    Wine()
        : PairArray()
    {
    }
// ...

Dziedziczysz z Pair<T1, T2> (T1 i T2 to parametry szablonu), ale konstruktor zawsze chce wołać konstruktor Pair<ArrayInt, ArrayInt>. Z listy inicjalizacyjnej możesz wołać tylko swój konstruktor, albo konstruktor klasy bazowej. Podobnych odwołań do PairArray (alias dla Pair<ArrayInt, ArrayInt>) jest w kodzie więcej i z tego na pewno wynikają problemy. 

Dodatkowo masz zszablonowany konstruktor, ale nigdzie z tego nie korzystasz.

Na razie tyle byłem w stanie znaleźć. Jeśli to nie rozwiązuje problemu, to pokaż treści błędów (w zasadzie mimo wszystko miło by było jak byś to zrobił).

PS: nie musisz wołać metod klasy bazowej w ten sposób jak teraz - możesz normalnie jak własną metode. Tak jak teraz (jawnie operatorem zasięgu mówiąc do kogo metoda należy) byłoby konieczne gdyby twoja klasa dziedzicząca definiowała takie same metody, a ty byś chciał zawołać tą z klasy bazowej.

komentarz 10 września 2017 przez B0nkers Początkujący (310 p.)
Czyli że w liście inicjalizacyjnej zamiast odwoływać się do PairArray, mam się odwołać do Pair?
komentarz 10 września 2017 przez criss Mędrzec (172,590 p.)
Do Pair<T1, T2>. Samo Pair to tylko szablon i nie jesteś w stanie się do niego odwołać.

Podobne pytania

+1 głos
0 odpowiedzi 317 wizyt
pytanie zadane 14 czerwca 2017 w Bezpieczeństwo, hacking przez RAD Obywatel (1,810 p.)
+1 głos
1 odpowiedź 3,480 wizyt
0 głosów
3 odpowiedzi 954 wizyt

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...