#include <iostream>
#include <string>
using namespace std;
/*
* 关于find1使用的数据结构,我们知道的信息
* 1.我们正在查找某个类型为int的值
* 2.我们正在一个int对象数组中进行查找
* 3.我们已经预先知道了数组中元素的数目
* 4.我们知道第一个元素的地址
*/
const int* find1(const int* array, int n, int x)
{
const int* p = array;
for(int i = 0; i < n; i++)
{
if (*p == x)
{
return p;
}
++p;
}
return 0;
}
/*
* 泛型化元素类型,首先去除的就是对int类型的依赖性
* find2的第三个参数是const T&对象的引用,因为x可能是复合数据类型
*/
template<class T>
T* find2(T* array, int n, const T& x)
{
T* p = array;
for(int i = 0; i < n; i++)
{
if (*p == x)
{
return p;
}
++p;
}
return 0;
}
/*
* 推迟计数:find3的第二个参数是一个指针,而find1和find2的第二个参数是数组个数。
* 因为对于某些数据结构几乎是不可能计算得到的---查找文件中的特定记录信息
* 用!=(p != beyond) 而不是<(p < beyond)来判断循环结束并不是偶然。从某种角度来看,两者没有区别:如果find3的输入有意义,则p就小于beyond,直到相等为止。
* 但是,由<加以总体排序通常也能用!来进行比较。另一方面,考虑一下我们以后可能会用到的用来替代指针的类型,它们可能能够很好的定义!=,而不是<
*/
template<class T>
T* find3(T* array, T* beyond, const T& x)
{
T* p = array;
while(p != beyond)
{
if (*p == x)
{
return p;
}
++p;
}
return 0;
}
/*
* 地址独立性:find1,find2和find3都依赖于传递来的指针的某些保留特征
* 1.可以把指针当作参数接受,并把他们作为结果返回
* 2.可以比较指针相不相等
* 3.可以解除引用指针,以便得到一个值:*p是这样一个值
* 4.可以递增指针,以指向下一个元素
* 代码声明了类型T*的变量,只要这些变量符合上述假设条件,那么就没有理由非要这些变量为指针。
* 假设通过把类型T*作为模板参数,我们取消了对指针的依赖性
*
*/
///find4是通用模板函数,只有传进find4的参数支持++,!=和*运算符。
template<class P, class T>
P find4(P start, P beyond, const T& x)
{
while(start != beyond && *start != x)
{
++start;
}
return start;
}
struct Node
{
string value;
Node* next;
};
class Nodep
{
public:
Nodep(Node* p) : pt(p){}
string& operator*()
{
return pt->value;
}
void operator++()
{
pt = pt->next;
}
friend int operator==(const Nodep&, const Nodep&);
friend int operator!=(const Nodep&, const Nodep&);
operator Node*()
{
return pt;
}
private:
Node* pt;
};
int operator==(const Nodep& p, const Nodep& q)
{
return p.pt == q.pt;
}
int operator!=(const Nodep& p, const Nodep& q)
{
return p.pt != q.pt;
}
int main()
{
Node node1;
node1.next = NULL;
node1.value = "node1";
Node node2;
node2.next = &node1;
node2.value = "node2";
Node node3;
node3.next = &node2;
node3.value = "node3";
Node node4;
node4.next = &node3;
node4.value = "node4";
Node node5;
node5.next = &node4;
node5.value = "node5";
Node* n = find4(Nodep(&node5), Nodep(0), "node5");
cout << n->value << endl;
return 0;
}