1. Wine类有一个string类对象成员(参见第4章)和一个Pair对象(参见本章);其中前者用于存储葡萄酒的名称,而后者有2个valarray
首先,本题要求Wine类包含一个string类对象和一个Pair对象,其中Pair对象包含2个valarray
首先,题目要求Pair类包含两个valarray
本题要求使用包含来做,那么Wine类将不能继承Pair对象,那么这种情况下只能将Pair的变量作为私有变量包含进Wine类,那么这里一般来说会在被包含类中声明一个set()方法用来初始化被包含类的初值。这种方法个人认为比较简单。
接下来就要给出Wine类声明,题目要求Wine类包含一个默认构造函数和一个规定好的构造函数,都对应加在公有部分,然后题目还要求Wine类包含一个GetBottles()方法,一个Label()方法,一个sum()方法,另外测试程序中还出现了Show()方法,也都对应加进去。
这里着重注意模板类的参数声明方式,具体请见详细代码。所有类的声明以及类方法定义见如下代码winec.h:
#ifndef WINEC_H_
#define WINEC_H_
#include
#include
#include
template
class Pair
{
private:
T1 a;
T2 b;
public:
void set(const T1 &yr, const T2 &bot);
Pair(const T1 & aval, const T2 & bval) : a(aval), b(bval) {}
Pair() {}
int Sum() const;
void Show(int y) const;
};
template
void Pair::set(const T1 &yr, const T2 &bot)
{
a = yr;
b = bot;
}
template
int Pair::Sum() const
{
return b.sum();
}
template
void Pair::Show(int y) const
{
for (int i = 0; i < y; i++)
{
std::cout << "\t\t" << a[i] << "\t\t" << b[i] << std::endl;
}
}
typedef std::valarray ArrayInt;
typedef Pair PairArray;
class Wine
{
private:
PairArray b;
std::string name;
int yrs;
public:
Wine(const char * l, int y, const int yr[], const int bot[]);
Wine(const char * l, int y);
void GetBottles();
std::string & Label();
int sum();
void Show();
};
Wine::Wine(const char * l, int y, const int yr[], const int bot[])
{
yrs = y;
name = l;
b.set(ArrayInt(yr, yrs), ArrayInt(bot, yrs));
}
Wine::Wine(const char * l, int y)
{
yrs = y;
name = l;
}
void Wine::GetBottles()
{
ArrayInt yr(yrs), bot(yrs);
std::cout << "Enter " << name << " data for " << yrs << " year(s):\n";
for (int i = 0; i < yrs; i++)
{
std::cout << "Enter year: ";
std::cin >> yr[i];
std::cout << "Enter bottles for that year: ";
std::cin >> bot[i];
}
b.set(yr, bot);
}
std::string & Wine::Label()
{
return name;
}
int Wine::sum()
{
return b.Sum();
}
void Wine::Show()
{
std::cout << "Wine: " << name << std::endl;
std::cout << "\t\tYear\tBottles\n";
b.Show(yrs);
}
#endif
有了.h的头文件之后,直接贴上题目给出的测试程序winec.cpp:
// winec.cpp -- check the wine class and pair, using Wine class with containment
#include "stdafx.h"
#include
#include "winec.h"
int main()
{
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);
holding.GetBottles();
holding.Show();
const int YRS = 3;
int y[YRS] = { 1993, 1995, 1998 };
int b[YRS] = { 48, 60, 72 };
Wine more("Gushing Grape Red", YRS, y, b);
more.Show();
cout << "Total bottles for " << more.Label() << ": " << more.sum() << endl;
cout << "Bye\n";
system("pause");
return 0;
}
这里说一下,与书中代码不同的是我在return 0;语句前面加了一句system("pause");因为正常情况下按照书上这样来运行,结果还没有看到,整个黑框框就一闪而过了,所以加上这一句让整个系统暂停一下,好看结果,书中提议的是使用两局cin.get();但是毕竟我们是为了暂停,而不是为了输入,所以我都是使用这一句。
运行结果如下所示:
可以看到运行结果和书中给出的预期完全一致。
2. 采用私有继承而不是包含来完成编程练习1.同样,一些typedef可能会有所帮助,另外,您可能还需要考虑诸如下面这样的语句的含义:
(代码省略)
您设计的类应该可以使用编程练习1中的测试程序进行测试。
本题要求在编程练习1的基础上,将包含关系修改为私有继承。那么Pair对象的变量就不需要作为私有变量了,直接继承即可。此时赋值的工作就可以通过初始化列表来完成,而且因为没有变量,需要使用类作用域限定来调用PairArray或者string。
头文件winec.h代码如下:
#ifndef WINEC_H_
#define WINEC_H_
#include
#include
#include
template
class Pair
{
private:
T1 a;
T2 b;
public:
void set(const T1 &yr, const T2 &bot);
Pa