P166 5.3

通常,类型与子类型之间的继承关系,反映出“is-a”的关系。例如,具有范围检验能力的ArrayRC是一种Array,Book是一种LibraryRentalMaterial,AudioBook是一种Book…以下各组说法,哪一些反应了“is-a”的关系?

  • member function是一种函数?✅
  • member function是一种class? ❌
  • construction是一种成员函数?✅
  • 飞机是一种交通工具?✅
  • 引擎是一种卡卡车?❌
  • 圆形是一种几何形状?✅
  • 正方形是一种矩形?✅
  • 汽车是一种飞机?❌
  • 借阅者是一种图书馆?❌

P166 5.4

图书馆提供以下出借馆藏分类,每一种都有自己的借出与归还方式。请将它们组织成一个继承层次体系:

  • library_lending_material
    • book
      • audio book
      • rental book
      • CD-ROM book
    • children’s puppet
    • record
    • video
    • video game
      • Sega
      • Sony Playstation
      • Nintenio

P189 6.1

试改写以下类,使它成为一个class template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class example {
public:
example(double min, double max);
example(const double *array, int size);
double& operator[](int index);
bool operator==(const example1&) const;
bool insert(const double*, int);
bool insert(double);
double min() const {return _min;}
double max() const {return _max;}
void min(double);
void max(double);
int count(double value) const;
private:
int size;
double *parray;
double _min;
double _max;
};

改写后为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template <typename elemType>
class example {
public:
example(const elemType &min, const elemType &max);
example(const elemType *array, int size);
elemType& operator[](int index);
bool operator==(const example1&) const;
bool insert(const elemType*, int);
bool insert(const elemType&);
elemType min() const {return _min;}
elemType max() const {return _max;}
void min(const elemType&);
void max(const elemType&);
int count(const elemType &value) const;
private:
int size;
elemType *parray;
elemType _min;
elemType _max;
};

P189 6.2

重新以template形式实现练习4.3的Matrix class,并扩充其功能,是它能够通过heap memory(堆内存)来支持任意行列大小。分配/释放内存的操作,请在constructor/destructor中进行。

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
template <typename elemType>
class Matrix {
friend Matrix<elemType>
operator+(const Matrix<elemType>&, const Matrix<elemType>&);
friend Matrix<elemType>
operator*(const Matrix<elemType>&, const Matrix<elemType>&);
public:
Matrix(int rows, int columns);
Matrix(const Matrix&);
~Matrix();
Matrix& operator=(const Matrix&);
void operator += (const Matrix&);
elemType& operator() (int row, int column) {
return _matrix[row * cols() + column];
}
const elemType& operator() (int row, int column) const {
return _matrix[row * cols() + column];
}
int rows() const {return _rows;}
int cols() const {return _cols;}
bool same_size(const Matrix &m) const {
return rows() == m.rows() && cols() == m.cols();
}
bool confortable(const Matrix &m) const {
return cols() == m.rows();
}
protected:
int _rows;
int _cols;
elemType *_matrix;
};

template <typename elemType>
Matrix<elemType> operator+(const Matrix<elemType> &m1, const Matrix<elemType> &m2) {
Matrix<elemType> result(m1);
result += m2;
return result;
}

template <typename elemType>
Matrix<elemType> operator*(const Matrix<elemType> &m1, const Matrix<elemType> &m2) {
Matrix<elemType> result(m1.rows(), m1.cols());
for (int i = 0; i < m1.rows(); i++) {
for (int j = 0; j < m1.cols(); j++) {
result(i, j) = 0;
}
}
for (int i = 0; i < m1.rows(); i++) {
for (int j = 0; j < m1.cols(); j++) {
result(i, j) += m1(i, j) * m2(i, j);
}
}
return result;
}

P203 7.1

以下函数没有检查可能的数据错误以及可能的执行失败。请找出此函数中所有可能发生错误的地方。本题并不考虑出现异常(exception)。

1
2
3
4
5
6
7
8
9
10
11
12
13
int *alloc_and_init(string file_name) {
ifstream infile(file_name);
int elem_cnt;
infile >> elem_cnt;
int *pi = allocate_array(elem_cnt);
int elem;
int index = 0;
while (infile >> elem)
pi[index++] = elem;
sort_array(pi, elem);
register_data(pi);
return pi;
}
  1. ifstream constructor接受的参数类型是const char*而非string。我们可以利用string的c_str()成员函数取得其C_style字符串表达。ifstream infile(file_name.c_str());
  2. infile被定义后,我们应该检查它是否成功打开:if (!infile){...}
  3. 无论何时,处理指针的时候,都应该注意到野指针的情况。必须随时注意指针是否的确指向实际存在的对象。若果allocate_array()无法分配足够内存,pi便会设置为0。必须做如下检验:if (!pi)

P203 7.2

下列函数被上题的alloc_and_ini()调用,执行失败时会发生异常:

1
2
3
allocate_array(); //发出异常noMem
sort_array(); //发出异常int
register_data(); //发出异常string

请安置一个或多个try块,以及相应的catch子句,以便能适当地处理这些异常。相应的catch子句中只需将错误打印出来即可。

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
int *alloc_and_init(string file_name) {
ifstream infile(file_name.c_str());
if (!infile) {
return 0;
}
int elem_cnt;
infile >> elem_cnt;
if (!infile) {
return 0;
}
int *pi = allocate_array(elem_cnt); //catch1
try {
int elem;
int index = 0;
while (infile >> elem)
pi[index++] = elem;
sort_array(pi, elem); //catch2
register_data(pi); //catch3
}
catch (const noMem &memFail) {
cout << "alloc_and_init(): allocate_array failure!\n" << memFail.show() << endl;
return 0;
}
catch (int &sortFail) {
cout << "alloc_and_init(): sort_array failure!\n" << "thrown integer value: " << sortFail << endl;
}
catch (string &registerFail) {
cout << "alloc_and_init(): register_data failure!\n" << "thrown string value: " << registerFail << endl;
return 0;
}
return pi;
}