目录
面向对象的再理解
面向对象方法将数据和对数据的基本操作处理函数都封装在一个类中,分别成为一个类的属性和成员函数。
整个类相当于定义了一个新的数据类型,然后根据具体问题建立该类的对象(即变量),通过对象调用合适的函数来解决实际问题。
实例
将1-20之间的奇数存入内存,之后在这组数中查找用户输入的任意一个整数并报告查找结果。
面向过程写法
void setValue(int b[], int n);
void find(int b[], int n, int x);//查找x
int main()
{ int data[10], a;
setValue(data, 10);
cout<<"a="; cin>>a;
find(data,10,a);
return 0;
}
void setValue(int b[], int n)
{ for (int i=0; i<n; i++) b[i]=2*i+1; }
void find(int b[], int n, int x)
{ int i;
for (i=0; i<n; i++) if (b[i]==x) break;
if (i==n)
cout<<x<<" doesn't exist in the array!";
else
cout<<x<<" exists in the array!";
cout<<endl;
}
面向对象写法
class arr
{ private:
int *a;
int maxSize, count;
public:
arr(int size);
void append(int x);
void find(int x);
~arr(){delete []a;}; };
arr::arr(int size)
{
a = new int[size];
maxSize = size;
count = 0;
}
void arr::append(int x)
{
if (count==maxSize) return;
a[count] = x;
count++;
}
void arr::find(int x)
{ int i;
for (i=0; i<count; i++)
if (a[i]==x) break;
if (i==count)
cout<<x<<" doesn't exist in the array!";
else cout<<x<<" exists in the array!";
cout<<endl;
}
int main()
{ arr obj(10);
int a;
for (int i=0; i<10; i++)
//将几个奇数放入对象
obj.append(2*i+1);
cout<<"a=";
cin>>a;
obj.find(a);
return 0;
}
泛型机制
Ø数据结构研究的是具有一定关系,且类型相同的一组元素。
Ø元素类型不特指某种具体类型,如整型、字符型或者复杂的结构类型。
Ø元素无论何种类型,它们在关系、基本操作处理方法上是一样的。
因此在数据类型上使用泛型机制: 函数模板、类模板
函数模板
函数模板定义
以max函数为例
template <class T>
T max(T &x, T &y) { if (x>y) return x; else return y;}
例子二(swap函数,注意不能与已存在的函数重名,包括内置的函数)
#include<iostream>
using namespace std;
template<class T>
void swap1(T &a,T &b)
{T tmp=a;
a=b;
b=tmp;
}
int main()
{
int a=12;
int b=45;
cout<<"a= "<<a<<" b="<<b<<endl;
swap1(a,b);
cout<<"a= "<<a<<" b="<<b<<endl;
return 0;
}
解释:上述代码在定义max函数对应的类模板时,数据类型标明的是T,此处的T未明确指出对应的类型,是因为所写模板可以适用于多种数据类型,当在其他位置调用此函数时,标明变量所对应的数据类型,系统会自动将数据类型传递到该函数,替换T,构成一个明确的函数。
函数模板的使用
int main
{ cout<<max(3,5)<<max('a','h')<<endl; }//自动检测类型,编译时产生模板函数
上述函数中,第一个3,5对应的是int类型,第二个'a','h'对应的是字符串类型,此处系统会根据所给数据根据模板函数自动产生函数定义。
类模板
类模板的定义
template <class elemType>
class arr
{ private:
elemType *a;
int maxSize, count;
public:
arr(int size);
//参数前加const,保护参数在函数执行中不得修改
void append(const elemType &x);
//参数表后加const,保护调用函数的对象的值不得修改
void find(const elemType &x)const;
~arr(){delete []a;};
};
template <class elemType>
//类模板中成员函数自动为函数模板
arr<elemType>::arr(int size)
{
a = new elemType[size];
maxSize = size;
count = 0;
}
template <class elemType>
void arr<elemType>::append(const elemType &x)
{
if (count==maxSize) return;
a[count] = x;
count++;
}
template <class elemType>
void arr<elemType>::find(const elemType &x) const
{
int i;
for (i=0; i<count; i++)
if (a[i]==x) break;
if (i==count)
cout<<x<<" doesn't exist in the array!";
else
cout<<x<<" exists in the array!";
cout<<endl;
}
类模板的使用
int main()
{ arr<int> obj1(10);
//<int>使得类模板实例化为一个模板类
const arr<int> obj2(20);
int a;
const int b=100;
for (int i=0; i<10; i++)
obj1.append(2*i+1);
cout<<"a="; cin>>a;
cout<<"In obj1: "; obj1.find(a);
cout<<"In obj1: "; obj1.find(b);
cout<<"In obj2: "; obj2.find(a);
return 0;
}
有关类模板的小结:
1、定义类时,要“加帽子”、“加胡须”。里面就可以使用一种泛化类型。
2、对类中每个成员函数实现时,也要戴帽子。里面使用泛化类型。
3、对于类模板,我们在使用时,写的外部函数,一定要注意泛化类型的实例化,比如上述main函数中的arr<int>注意加上int。