实验内容
利用C++语言,参考教材,实现Triangular类开发与测试,包括:
- 构造函数、析构函数
- 数据成员定义、函数成员定义
- 利用运算符重载技术,实现Iterator
- 给出实验结果截图及实验分析
实验原理
2.1 类的基本结构包含哪些部分
关键字,类名,访问修饰符,变量,方法。
类定义是以关键字 class 开头,后跟类的名称。类的主体是包含在一对花括号中。类定义后必须跟着一个分号或一个声明列表。
关键字 public 确定了类成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。您也可以指定类的成员为 private 或 protected。
2.2 构造函数、析构函数的特点、用法分析
类的构造函数是一种特殊的函数,在创建一个新的对象时调用。类的析构函数也是一种特殊的函数,在删除所创建的对象时调用。
构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。
析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。
2.3
运算符重载,说白了就是重新定义原有的运算符以适合泛型指针类的运算。可以像定义成员函数那样重新定义运算符。
运算符函数很像普通函数,但是运算符函数不用指定函数名。只需要在运算符前加上关键字 operator 即可。
重载规则:
-
. .* :: ?: 这四个运算符不能重载
-
运算符的操作数个数不能变。例如“==”只能有两个操作数
-
运算符的优先级不能变
-
运算符函数的参数列表中,至少有一个参数为 class 类型。这是人为定义的。
-
人为区分了i和i的运算符重载方式
嵌套类型:
Typedef可以为某个类型设定另一个不同的名称。
代码
Triangular.h
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
| #include "triangularIterator.h" #include <vector> #include <ostream> #include <iostream> using namespace std; class trianguluarIterator; class Triangular { public: static vector<int> _elems; friend class trianguluarIterator; typedef trianguluarIterator iterator; Triangular(int len = 1, int bp = 1); Triangular(const Triangular &); Triangular &operator=(const Triangular &rhs); int length() const { return _length; } int beg_pos() const { return _beg_pos; } int elem(int pos) const; void length(int nlen) { _length = nlen; } void beg_pos(int npos) { _beg_pos = npos; } bool next(int &val) const; void next_reset() const { _next = 1; } static bool is_elem(int); static void gen_elements(int length); static void gen_elems_to_value(int value); static void display(int length, int beg_pos, ostream &os = cout);
triangularIterator begin() const { return triangularIterator(_beg_pos); } triangularIterator end() const { return triangularIterator(_beg_pos + _length); }
private: int _length; int _beg_pos; mutable int _next; enum { _max_elems = 1024 }; };
|
Triangular.cpp
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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
| #include "Triangular.h"
ostream &operator<<(ostream &os, const Triangular &rhs) { os << "( " << rhs.beg_pos() << " , " << rhs.length() << " ) "; rhs.display(rhs.length(), rhs.beg_pos(), os); return os; }
istream &operator>>(istream &is, Triangular &rhs) { char ch1, ch2; int bp, len;
is >> ch1 >> bp >> ch2 >> len; rhs.beg_pos(bp); rhs.length(len); rhs.next_reset(); return is; }
Triangular::Triangular(int len, int beg_pos) : _length(len > 0 ? len : 1), _beg_pos(beg_pos > 0 ? beg_pos : 1) { _next = _beg_pos; int elem_cnt = _beg_pos + _length; if (_elems.size() < elem_cnt) { gen_elements(elem_cnt); } }
Triangular::Triangular(const Triangular &rhs) : _length(rhs._length), _beg_pos(rhs._beg_pos), _next(rhs._next) { }
int sum(const Triangular &trian) { if (0 == trian.length()) { return 0; } int val, sum = 0; trian.next_reset(); while (trian.next(val)) { sum += val; } return sum; }
int Triangular::elem(int pos) const { return _elems[pos - 1]; }
bool Triangular::next(int &value) const { if (0 == _next) { return false; } if (_next < _beg_pos + _length) { value = _elems[_next++]; return true; } _next = 0; return false; }
Triangular &Triangular::operator=(const Triangular &rhs) { if (this != &rhs) { _length = rhs._length; _beg_pos = rhs._beg_pos; _next = 1; } return *this; }
vector<int> Triangular::_elems;
bool Triangular::is_elem(int value) { if (!_elems.size() || _elems[_elems.size() - 1] < value) { gen_elems_to_value(value); } return find(_elems.begin(), _elems.end(), value) != _elems.end(); }
void Triangular::gen_elements(int length) { if (length < 0 || length > _max_elems) { cerr << "Triangular Sequence: oops: invalid size: "; cerr << length << " -- max size is "; cerr << _max_elems << endl; return; } if (_elems.size() < length) { int ix = _elems.size() ? _elems.size() + 1 : 1; while (ix <= length) { _elems.push_back(ix * (ix + 1) / 2); ++ix; } } }
void Triangular::gen_elems_to_value(int value) { int ix = _elems.size(); if (0 == ix) { _elems.push_back(1); ix = 1; } while (_elems[ix - 1] < value && ix < _max_elems) { _elems.push_back(ix * (ix + 1) / 2); ++ix; } if (ix == _max_elems) { cout << "Triangular Sequence: oops: value too large " << endl; cout << value << " -- exceeds max size of " << endl; cout << _max_elems << endl; } }
void Triangular::display(int length, int beg_pos, ostream &os) { if (length <= 0 || beg_pos <= 0) { cout << "invalid parameters -- unable to fulfill request: "; cout << length << ", " << beg_pos << endl; return; } int elems = beg_pos + length - 1; if (_elems.size() < elems) { gen_elements(elems); } for (int ix = beg_pos - 1; ix < elems; ++ix) { os << _elems[ix] << ' '; } }
triangularIterator.h class triangularIterator { public: triangularIterator(int index) : _index(index - 1) {} bool operator==(const triangularIterator &) const; bool operator!=(const triangularIterator &) const; int operator*() const; triangularIterator &operator++(); triangularIterator operator++(int);
private: int _index; };
triangularIterator.cpp #include "Triangular.h" bool triangularIterator::operator==(const triangularIterator &rhs) const { return _index == rhs._index; }
bool triangularIterator::operator!=(const triangularIterator &rhs) const { return !(*this == rhs); }
int triangularIterator::operator*() const { return Triangular::_elems[_index]; }
triangularIterator &triangularIterator::operator++() { ++_index; return *this; }
triangularIterator triangularIterator::operator++(int) { triangularIterator tmp = *this; ++_index; return tmp; }
|
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <iostream> #include "Triangular.h"
int main() { cout << "input length a and begin_pos b:" << endl; int a, b; cin >> a >> b; Triangular tri(a, b); triangularIterator it = tri.begin(); triangularIterator end_it = tri.end(); cout << "Triangular Series of " << tri.length() << " elements\n"; Triangular::display(tri.length(), tri.beg_pos(), cout); while (it != end_it) { cout << *it << ' '; ++it; } cout << endl; return 0; }
|
实验结果及分析
输入10和5
输入29和21
输入100和100
综上,可以发现重载的运算符++, --, !=, ==, 以及*(指针间接引用)完美运行。