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

Вместо включения используйте закрытое наследование - C++

Восстановить пароль Регистрация
 
zahvad
0 / 0 / 0
Регистрация: 22.07.2014
Сообщений: 8
25.07.2014, 13:29     Вместо включения используйте закрытое наследование #1
Здравствуйте. Изучаю С++ по книге Прата С. "Язык программирования С++. Лекции и упражнения". Столкнулся с проблемой.
Есть задание: Выполните еще раз упражнение 1, но вместо включения используйте закрытое
наследование. Здесь также могут пригодиться несколько объявлений typedef.
Подумайте, как можно применить следующие операторы:
PairArray::operator=(PairArray(Arraylnt() , Arraylnt()));
cout << (const string &)(*this);
Полученный класс должен работать с тестовой программой, приведенной в
упражнении 1.
Все сделал, все работает. cout << (const string &)(*this) нашел применение сам собой. А вот PairArray::operator=(PairArray(Arraylnt() , Arraylnt())) - понятия не имею куда определить. Куда я его только не пробовал пихать: в конструкторы, в перегруженную операцию присваивания, в main() что-то пытался чудить. Везде ошибки. Смысл этого оператора понятен: вызывается перегруженная операция присваивания из класса PairArray. В качестве аргумента выступает безымянный объект класса PairArray, который , в свою очередь, создается конструктором Pair(const T1 & aval, const T2 & bval). В качестве аргументов конструктора Pair выступают valarray<int>(), то есть массивы с нулевым размером.
Помогите пожалуйста определить, куда нужно вставить этот оператор: PairArray::operator=(PairArray(Arraylnt() , Arraylnt())). Само собой, оператор должен оставаться в неизменном виде, как этого требует задание.
Код программы представлен ниже. Программа полностью работоспособна.
1) Заголовочный файл:
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
template <class T1, class T2> 
class Pair
{ 
private: 
T1 a; 
T2 b; 
public: 
T1 & first() { return a; } 
T2 & second() { return b; } 
T1 first () const { return a; } 
T2 second() const { return b; }
Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) { }
Pair() {}
Pair<T1,T2> & operator=(Pair<T1,T2> & P);
};
 
typedef valarray<int> ArrayInt;
typedef Pair<ArrayInt,ArrayInt> PairArray;
 
 
 
class Wine : private PairArray, private string {
private:
    int count;
public:
    Wine() : string("none"), PairArray(), count(0) {}
    Wine(const char * l, int y, const int yr[], const int bot[]) : string(l), count(y), PairArray(ArrayInt (yr,y),ArrayInt (bot,y)) {}
    Wine(const char * l, int y) : string(l), count(y), PairArray(ArrayInt (y),ArrayInt (y)) {}
    void GetBottles();
    const string & Label() { return (const string &) (*this); }
    int sum() const;
    void Show() const;
};
2) Файл реализации:
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
template <class T1, class T2>
Pair<T1,T2> & Pair<T1,T2>::operator=(Pair<T1,T2> & P) {
    a=P.a;
    b=P.b;
    return *this;
}
 
 
void Wine::GetBottles() {
    cout << "Enter " << Label() << " data for " << count << " year(s): \n";
    for(int i=0;i<count;i++) {
        cout << "Enter year: ";
        cin >> PairArray::first()[i];
        cout << "Enter bottles for that year: ";
        cin >> PairArray::second()[i];
    }
}
int Wine::sum() const {
    int sum=0;
    for(int i=0;i<count;i++) sum+=PairArray::second()[i];
    return sum;
}
void Wine::Show() const {
    cout << "Wine: " << (const string &)(*this) << endl;
    cout << "\tYear\tBottles\n";
    for(int i=0;i<count;i++) cout << "\t" << PairArray::first()[i] << "\t" << PairArray::second()[i] << endl;
}
3) Файл исходного кода:
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
void 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(); // вывод содержимого объекта 
Wine Tempp;
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"; 
 
 
cout << "\nDone!\n\n";
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zahvad
0 / 0 / 0
Регистрация: 22.07.2014
Сообщений: 8
29.07.2014, 11:13  [ТС]     Вместо включения используйте закрытое наследование #2
Сам додумался. Оператор "PairArray::operator=(PairArray(Arraylnt() , Arraylnt()));" делает ни что иное, как очистку части PairArray из любого класса - потомка. То есть он создает пустой объект PairArray и присваивает его вызвавшему. Исходя из этого я определил метод в классе Wine:
C++
1
2
3
4
5
void Wine::Clear() {
    count=0;
    string::operator=("none");
    PairArray::operator=(PairArray(ArrayInt() , ArrayInt()));
}
Как видите, оператор "PairArray::operator=(PairArray(ArrayInt() , ArrayInt()));" находится в ней в неизменном состоянии, как этого и требует задание. Метод прекрасно функционирует, очищая объект а точнее, приводя его в такое состояние, которое создает конструктор по умолчанию.
Надеюсь, это кому-то поможет.
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
29.07.2014, 15:17     Вместо включения используйте закрытое наследование #3
Цитата Сообщение от zahvad Посмотреть сообщение
Файл реализации:
C++
1
template <class T1, class T2>
реализация шаблона должны быть в хедере

Добавлено через 57 секунд
Цитата Сообщение от zahvad Посмотреть сообщение
C++
1
void main() {
это тоже Прата научил?
zahvad
0 / 0 / 0
Регистрация: 22.07.2014
Сообщений: 8
29.07.2014, 15:40  [ТС]     Вместо включения используйте закрытое наследование #4
Цитата Сообщение от Jupiter Посмотреть сообщение
реализация шаблона должны быть в хедере
Я знаю, спасибо. Эту часть кода я взял из книги. Она, как не странно, работает. Сам удивился.
Цитата Сообщение от Jupiter Посмотреть сообщение
это тоже Прата научил?
А что не так? Зато "return 0;" в конце не нужен, как в случает с "int main()".
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
29.07.2014, 15:42     Вместо включения используйте закрытое наследование #5
zahvad, Не так то, что это нестандартно. Есть несколько стандартных объявлений функции main. Но во всех них она должна возвращать int. Ну и да, return 0 не обязателен в любом случае, в С++ по дефолту из main возвращается 0.
zahvad
0 / 0 / 0
Регистрация: 22.07.2014
Сообщений: 8
29.07.2014, 16:02  [ТС]     Вместо включения используйте закрытое наследование #6
Если оно всегда работает, то все равно не стоит использовать мой вариант? Если не стоит, объясните пожалуйста подробно, чем вариант "int main()" лучше? Мне интересно разобраться в тонкостях языка.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
29.07.2014, 16:07     Вместо включения используйте закрытое наследование #7
Тем, что программа должна вернуть хоть какое то значение системе при завершении. В стандарте языка есть несколько прототипов функции main и все они возвращают int. Как уже сказалаи, в C++ необязательно возвращать 0 из этой функции, это подразумевается по умолчанию. То, что работает прототип void main() - отголоски прошлого. Многие современные компиляторы уже не пропустят такой код.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.07.2014, 16:14     Вместо включения используйте закрытое наследование
Еще ссылки по теме:

C++ Закрытое наследование. Вывод строки
C++ Открытое и закрытое хеширование
Пояснить, почему в примере не рекомендуется использовать закрытое наследование C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
zahvad
0 / 0 / 0
Регистрация: 22.07.2014
Сообщений: 8
29.07.2014, 16:14  [ТС]     Вместо включения используйте закрытое наследование #8
Цитата Сообщение от Toshkarik Посмотреть сообщение
Тем, что программа должна вернуть хоть какое то значение системе при завершении. В стандарте языка есть несколько прототипов функции main и все они возвращают int. Как уже сказалаи, в C++ необязательно возвращать 0 из этой функции, это подразумевается по умолчанию. То, что работает прототип void main() - отголоски прошлого. Многие современные компиляторы уже не пропустят такой код.
Понял, спасибо. Буду знать.
Yandex
Объявления
29.07.2014, 16:14     Вместо включения используйте закрытое наследование
Ответ Создать тему
Опции темы

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