Форум программистов, компьютерный форум CyberForum.ru

Повторное использование кода в C++ - C++

Восстановить пароль Регистрация
 
anakonda3247gm
 Аватар для anakonda3247gm
0 / 0 / 0
Регистрация: 08.04.2013
Сообщений: 2
08.04.2013, 14:30     Повторное использование кода в C++ #1
Всем доброго дня! Прошу помочь начинающему. В данный момент обучаюсь по книге Прата С.. Застрял на задаче про использование класса valarray. Прошу помочь разобраться в создании конструкторов.

Имеется:
Класс Wine (Вино) содержит объект-член типа string для названия вина и объект Pair из объектов valarray<int>. Первый член каждого объекта Pair содержит год сбора винограда, а второй член — количества бутылок с вином урожая этих лет. Например, первый объект valarray объекта Pair содержит годы 1988, 1992 и 1996, а второй объект valarray — количества бутылок: 24, 48 и 144.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <class T1, class T2>
class Pair
{
private:
    T1 a;
    T2 b;
public:
    T1 & first();
    T2 & second();
    T1 first() const { return a; }
    T2 second() const { return b; }
    Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) { }
    Pair() {}
};
Для упрощения кода могут быть полезными следующие объявления typedef:
C++
1
2
typedef std::valarray<int> Arraylnt; 
typedef Pair<ArrayInt, Arraylnt> PairArray;
Класс Wine должен иметь конструктор по умолчанию и, как минимум, следующие
конструкторы:

C++
1
2
3
4
5
// Инициализация label значением l, количество лет - у,  годы урожая - уг[], количество бутылок - bot [ ] 
Wine (const char * l, int у, const int yr[], const int bot[]); 
 
// Инициализация label значением 1, количество лет - у, создаются объекты массива размером у 
Wine (const char * l, int у);
Так же класс Wine должен иметь некоторые методы:
GetBottles(); - предлагает ввод соотв. значений для года урожая и количества бутылок.
Show(); -
Label(); - возвр. ссылку на название вина.
sum (); - возвр. общее количество бутылок во втором бъекте valarray<int> из объекта Pair.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Wine
{
    string name;
    PairArray p;
public:
    Wine();
    Wine (const char * l, int у, const int yr[], const int bot[]); 
    Wine (const char * l, int у); 
 
    GetBottles();
    Show();
    Label();
    sum ();
}
Программа должна предлагать пользователю ввести название вина, количество элементов в массиве, а также год и количество бутылок для каждого элемента массива. Программа должна использовать эти данные для создания объекта Wine и вывода информации, хранимой в объекте.

Так же приведен пример тестовой программы и вывод на экран.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main ( void ) 
{ 
    using std::cin;
    using std::cout;
    using std::endl;
 
    cout << "Enter name of wine: "; // ввод названия вина 
    char lab[50];
    cin.getline(lab, 50);
 
    cout << "Enter number of years: "; // ввод количества годов сбора винограда 
    int yrs; 
    cin >> yrs;
 
    Wine holding(lab, yrs); // сохранение названия, лет, 
    // создание массивов из yrs элементов 
 
    holding.GetBottles (); // предложение ввести год и количество бутылок 
    holding.Show (); // вывод содержимого объекта 
 
    const int YRS = 3; 
    int y[YRS] = {1993, 1995, 1998}; 
    int b[YRS] = { 48, 60, 72}; 
 
    // Создание нового объекта, инициализация 
    // с использованием данных из массивов у и b 
    Wine more("Gushing Grape Red",YRS, y, b) ; 
    more.Show(); 
 
    cout << "Total bottles for " << more.Label() // используется метод Label() 
         << ": " << more, sum () << endl; // используется метод sum() 
    cout << "Bye\n"; 
    return 0; 
}
А так может выглядеть вывод программы:

Enter name of wine: Gully Wash
Enter number of years: 4
Enter Gully Wash data for 4 year(s) :
Enter year: 1988
Enter bottles for that year: 42
Enter year: 1994
Enter bottles for that year: 58
Enter year: 1998
Enter bottles for that year: 122
Enter year: 2001
Enter bottles for that year: 144
Wine: Gully Wash
Year Bottles
1988 42
1994 58
1998 122
2001 144
Wine: Gushing Grape Red
Year Bottles
1993 48
1995 60
1998 72
Total bottles for Gushing Grape Red: 180
Bye
2.

Очень прошу объяснить, как создать конструкторы класса Wine на основе шаблона Pair и valarray.
Подозреваю, что туплю "не по-детски", но банально застрял. Надеюсь на довольно вразумительный "пинок" с вашей стороны.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
anmartex
...
 Аватар для anmartex
1699 / 1192 / 494
Регистрация: 12.02.2013
Сообщений: 1,978
08.04.2013, 20:21     Повторное использование кода в C++ #2
На мой взгляд, использовать пару массивов - не логично. Более правильно - массив пар. Кстати, в STL уже есть класс pair. А по вашему вопросу, я бы сделал так (описаны только конструкторы и перегрузка перенаправления вывода):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <string>
#include <vector>
 
class Wine
{
   public:
      typedef std::pair<int, int> Info;
      typedef std::vector<Info> InfoArray;
 
   private:
      std::string name;
      InfoArray info;
 
   public:
      Wine(const std::string& theName): name(theName) { ; };
 
      Wine(const std::string& theName, const Info& theInfo)
         : name(theName), info(&theInfo, &theInfo + 1) { ; }
 
      Wine(const std::string& theName, const Info theInfo[], size_t count)
         : name(theName), info(theInfo, theInfo + count) { ; }
 
      Wine(const std::string& theName, const InfoArray& theInfoArray)
         : name(theName), info(theInfoArray) { ; }
 
      friend std::ostream& operator << (std::ostream& out, const Wine& wine)
      {
         out << "Wine = " << wine.name << std::endl;
 
         Wine::InfoArray::const_iterator it;
         for (it = wine.info.begin(); it != wine.info.end(); ++it)
         {
            out << it->first << " " << it->second << std::endl;
         }
 
         return out;
      }
};
 
int main()
{
   Wine first("first");
 
   Wine second("second", Wine::Info(1970, 20));
 
   const Wine::Info info[] = {Wine::Info(1970, 25),
                              Wine::Info(1975, 50),
                              Wine::Info(1960, 11)};
 
   Wine last("last", info, sizeof(info) / sizeof(*info));
 
   std::cout << first  << std::endl
             << second << std::endl
             << last   << std::endl;
 
   return 0;
}
Название: image.PNG
Просмотров: 220

Размер: 4.2 Кб

Результат на codepad.org
anakonda3247gm
 Аватар для anakonda3247gm
0 / 0 / 0
Регистрация: 08.04.2013
Сообщений: 2
09.04.2013, 10:15  [ТС]     Повторное использование кода в C++ #3
Спасибо! Ситуация стала проясняться))
faradej
0 / 0 / 0
Регистрация: 25.04.2013
Сообщений: 67
23.06.2013, 09:18     Повторное использование кода в C++ #4
Вряд ли получу ответ, но просто учусь по этой же книге и столкнулся с этой же проблемой.

@anmartex, у вас нормально скомпилировалась программа, дело в том что у меня появляется ошибка про

невозможно преобразовать параметр 2 из "int" в "Pair::Type_year &"

это из-за этого
C++
1
2
3
int yrs;
cin >> yrs;
Wine holding(lab, yrs);
Если бы yrs был valarray то нормально, но он int, такое условие задачи.
anmartex
...
 Аватар для anmartex
1699 / 1192 / 494
Регистрация: 12.02.2013
Сообщений: 1,978
23.06.2013, 09:37     Повторное использование кода в C++ #5
@faradej, конструктора принимающего вторым параметром int в моей реализации нет.
C++
1
2
3
int year;
cin >> year;
Wine holding(lab, Wine::Info(year, 1));
DESergik
1 / 1 / 0
Регистрация: 26.12.2012
Сообщений: 17
31.12.2014, 13:45     Повторное использование кода в C++ #6
Вот мой вариант, полностью написан по условию задачи. То же по этой книге учусь
Основной код программы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <locale>    // Строчка для Русского языка
#include "H_task_1.h"
 
int main()
{
    setlocale(LC_ALL,"Russian"); // Строчка для Русского языка
    
    cout<<"Enter name of wine: "; // ввод названия вина
    char lab[50];
    cin.getline(lab, 50);
    cout<<"Enter number of years: "; // ввод количества годов сбора винограда
    int yrs;
    cin>>yrs;
    Wine holding(lab, yrs); // сохранение названия, лет, создание массивов из yrs элементов
    holding.GetBottles();   // предложение ввести год и количество бутылок
    holding.Show();         // вывод содержимого объекта
    const int YRS=3;
    int у[YRS]={1993, 1995, 1998};
    int b[YRS]={48, 60, 72}; 
    // Создание нового объекта, инициализация с использованием данных из массивов у и b
    Wine more("Gushing Grape Red", YRS, у, b);
    more.Show();
    cout<<"Total bottles for "<<more.Label() // используется метод Label()
        <<": "<<more.sum()<<endl; // используется метод sum()
    cout<<"Bye\n";
    
    system("pause");
    return 0;
}
Заголовочный файл:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// H_task_1.h -- класс Wine
#ifndef H_TASK_1_H_
#define H_TASK_1_H_
 
#include <iostream>
#include <string>
#include <valarray>
#include <iomanip>
using std::cout;
using std::endl;
using std::cin;
 
 
// Шаблон с несколькими параметрами типа:
template <class T1, class T2>
class Pair
{
private:
    T1 a; // Значение вида 1
    T2 b; // Значение вида 2
public:
    Pair() {} // Конструктор по умолчанию
    Pair(const T1 &aval, const T2 &bval) : a(aval), b(bval) { } // Конструктор
    // Методы присвоения хранимым величинам новых значений:
    T1 & first();  // Ввод значения 1-го вида
    T2 & second(); // Ввод значения 2-го вида
    // Методы печати хранимых значений:
    T1 first() const { return a; }  // Печать значения 1-го вида
    T2 second() const { return b; } // Печать значения 2-го вида
};
 
// Методы присвоивания хранимым величинам новых значений:
// Ввод значения 1-го вида
template<class T1, class T2>
T1 & Pair<T1,T2>::first()
{
    return a;
}
 
// Ввод значения 2-го вида
template<class T1, class T2>
T2 & Pair<T1,T2>::second()
{
    return b;
}
 
 
// Основной класс (использует включение):
class Wine
{
private:
    std::string label; // Используется объект string для имени
    // Объект Pair состоит из объектов valarray<int>. Для упрощения введем объявления typedef:
    typedef std::valarray<int> ArrayInt;
    // Первый член объекта Pair содержит год сбора винограда, а второй член — количества бутылок с вином урожая этих лет:
    typedef Pair<ArrayInt, ArrayInt> PairArray;
    PairArray wine_inf;
    int years; // Количество лет (размерность двух массивов)
public:
    Wine() : label("Empy name"), wine_inf() {} // #0: Коструктор по умолчанию - во 2-ом операнде вызывает конструктор класа Pair по умолчанию, который создает два массива int нулевого размера
    // Коструктор #1: Инициализация label значением l, количество лет (размерность двух массивов) - у, годы урожая - yr[], количество бутылок - bot[]:
    Wine(const char *l, int y, const int yr[], const int bot[]) : label(l), years(y), wine_inf(ArrayInt(yr, y), ArrayInt(bot, y)) {}
    // Коструктор #2: Инициализация label значением l, количество лет - у, т.е. создаются 2 массива int размером y:
    Wine (const char *l, int y) : label(l), years(y), wine_inf(ArrayInt(y), ArrayInt(y)) {}
    void GetBottles(); // Запрашивает у пользователя количество лет и предлагает пользователю ввести соответствующие значения для года урожая и количества бутылок
    const std::string & Label() const { return label; }; // Возвращает название вина
    const void Show() const; // Вывод содержимого объекта
    int sum(); // Возвращает общее количество бутылок во втором объекте valarray<int> из объекта Pair
};
 
// Предлагает пользователю ввести соответствующие значения для года урожая и количества бутылок
void Wine::GetBottles()
{
    cout<<"Enter "<<Label()<<" data for "<<years<<" year(s):\n";
    for (int i=0; i<years; i++)
    {
        cout<<"Enter year: ";
        cin>>wine_inf.first()[i];
        cout<<"Enter bottles for that year: ";
        cin>>wine_inf.second()[i];
    }
    cout<<endl;
}
 
// Вывод содержимого объекта
const void Wine::Show() const
{
    cout<<"Wine: "<<Label()<<endl;
    cout<<std::setw(10)<<"Year"<<"    "<<"Bottles"<<endl;
    for (int i=0; i<years; i++) // или можно wine_inf.first().size()
        cout<<std::setw(10)<<wine_inf.first()[i]<<"    "<<wine_inf.second()[i]<<endl;
    cout<<endl;
}
 
// Возвращает общее количество бутылок во втором объекте valarray<int> из объекта Pair
int Wine::sum()
{
    return wine_inf.second().sum();
}
#endif
Yandex
Объявления
31.12.2014, 13:45     Повторное использование кода в C++
Ответ Создать тему
Опции темы

Текущее время: 14:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru