程序设计的学习真是越来越有趣啦!也需要花更多时间和精力来仔细体会每一个程序的内部机理。
本次Debug经验:在每次需要添加新的运算符重载时,往往是缺少类型匹配所致。不仅函数调用需要类型严丝合缝,运算符重载也是如此。
//main.cpp
#include <iostream>
#include <cstdlib>
#include "ArrayCollection.h"
#include "LinkedListCollection.h"
#include "Score.h"
#include "isPass.h"
using namespace std;
template <class _iterator, class T>
void analyze(_iterator begin, _iterator end, IsPass<_iterator, T> isPass){
int passed = 0, count = 0;
for(_iterator p = begin; p != end; p++){
if(isPass(p))
passed++;
count++;
}
cout << "passing rate = " << (float)passed / count << endl;
}
int main(int argc, char** argv) {
Score sarray[3];
sarray[0] = Score(60, 60, 60);
sarray[1] = Score(70, 70, 70);
sarray[2] = Score(50, 80, 80);
ArrayCollection<Score> collection3(3, sarray);
LinkedListCollection<Score> collection4;
for(int i = 0; i < 3; i++)
collection4.addFirst(sarray[i]);
analyze(sarray, sarray + 3, IsPass<Score*, Score>(Score(70, 60, 60)));
analyze(collection3.begin(), collection3.end(), IsPass<Score*, Score>(Score(50, 60, 60)));
analyze(collection4.begin(), collection4.end(), IsPass<LinkedListIterator<Score>, Score>(Score(60, 60, 60)));
system("PAUSE");
return EXIT_SUCCESS;
}
//Score.h
#ifndef Score_h
#define Score_h
#include <iostream>
using namespace std;
struct Score{
float value[3];
Score(){}
Score(float f1, float f2, float f3){
value[0] = f1;
value[1] = f2;
value[2] = f3;
}
Score& operator=(const Score& s){
value[0] = s.value[0];
value[1] = s.value[1];
value[2] = s.value[2];
return *this;
}
bool operator>=(float pass){
return (value[0] >= pass && value[1] >= pass && value[2] >= pass);
}
bool operator>=(Score pass){
return (value[0] >= pass.value[0] && value[1] >= pass.value[1] && value[2] >= pass.value[2]);
}
};
ostream& operator<<(ostream& out, const Score& s){
out << '{' << s.value[0] << ',' << s.value[1] << ',' << s.value[2] << '}';
return out;
}//注意这个流运算符重载不在类Score的内部定义,而要拿到外面来
#endif
//IsPass.h
#ifndef IsPass_h
#define IsPass_h
template <class _iterator, class T>
class IsPass{
T _pass;
public:
IsPass(const T& pass):_pass(pass){}
bool operator()(const _iterator& p){
return (*p >= _pass);
}
};
#endif
//ArrayCollection.h
#ifndef ArrayCollection_h
#define ArrayCollection_h
template <class T>
class ArrayCollection{
T* _data;
int _size;
public:
ArrayCollection():_size(10){
_data = new T[_size];
}
ArrayCollection(int size):_size(size){
_data = new T[_size];
}
ArrayCollection(int size, T* data):_size(size){
_data = new T[_size];
for(int i = 0; i < size; i++)
*(_data + i) = *(data + i);
}
~ArrayCollection(){
delete[] _data;
}
T* begin(){
return _data;
}
T* end(){
return (_data + _size);
}
};
#endif
//LinkedListCollection.h
#ifndef LinkedListCollection_h
#define LinkedListCollection_h
template <class T>
struct LinkedListNode{
T _data;
LinkedListNode *_next;
LinkedListNode():_next(NULL){}
LinkedListNode(T data):_data(data), _next(NULL){}
LinkedListNode(T data, LinkedListNode<T>* next):_data(data), _next(next){}
//注意上面这一行的第二个形参,其类型必须是LinkedListNode<T>*,否则
//将与 LinkedListCollection::addFirst(T&) 中的_head的类型不匹配,编译器会报错!
};
template <class T>
struct LinkedListIterator{
LinkedListNode<T> *pointer;
LinkedListIterator(LinkedListNode<T> *p):pointer(p){}
LinkedListIterator(const LinkedListIterator<T>& it):pointer(it.pointer){}
LinkedListIterator<T>& operator++(){
pointer = pointer->_next;
return *this;
}
const LinkedListIterator<T> operator++(int){
LinkedListIterator<T> temp = *this;
pointer = pointer->_next;
return temp;
}
T& operator*() const{
return pointer->_data;
}
T* operator->() const{
return &(pointer->_data);
}
bool operator!=(const LinkedListIterator<T> &other){
return pointer != other.pointer;
}
bool operator==(const LinkedListIterator<T> &other){
return pointer == other.pointer;
}
};
template <class T>
class LinkedListCollection{
LinkedListNode<T>* _head;
public:
LinkedListCollection():_head(NULL){}
~LinkedListCollection(){clear();}
bool empty(){return (_head == NULL);}
void addFirst(const T& data){
_head = new LinkedListNode<T>(data, _head);
}
bool removeFirst(){
if(_head != NULL){
LinkedListNode<T>* p = _head;
_head = _head->_next;
delete p;
return true;
}
else{
return false;
}
}
T* getFirst(){
return (_head != NULL) ? &(_head->_data) : NULL;
}
LinkedListNode<T>* lastNode(){
LinkedListNode<T>* p;
for(p = _head; p->_next != NULL; p = p->_next) ;
return p;
}
void addLast(const T& data){
if(_head != NULL){
lastNode()->_next = new LinkedListNode<T>(data);
}
else{
_head = new LinkedListNode<T>(data);
}
}
T* getLast(){
return (_head != NULL) ? &(lastNode()->_data) : NULL;
}
bool removeLast(){
if(_head != NULL){
if(_head->_next != NULL){
LinkedListNode<T>* p;
for(p = _head; p->_next != NULL; p = p->_next) ;
delete p->_next;
p->_next = NULL;
return true;
}
else{
delete _head;
_head = NULL;
return true;
}
}
else
return false;
}
void clear(){
while(removeFirst()) ;
}
LinkedListIterator<T> begin(){
return LinkedListIterator<T>(_head);
}
LinkedListIterator<T> end(){
return LinkedListIterator<T>(NULL);
}
};
#endif