通过使用c++中的泛型编程机制模板,实现可以对任意类型的数组里面的数据进行排序。包括我们自己定义的一个类模板的类型。
首先我们对普通的类型int和float类型的数组进行排序,排序的模板:
template <typename T>
class sort_demo{
public:
static void sort(T *data, int len, bool (*compare)(T &a, T &b))
{
T temp;
assert(len >= 1);
cout << "len=" << len << " :";
for (int i = 0; i < len; i++)
{
for (int j = (i + 1); j < len; j++)
{
if (compare(data[i], data[j]))
{
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
}
};
里面的成员方法sort具体的算法是冒泡排序, 其中参数bool (*compare)(T &a, T &b)也是函数模板的指针,并且这个指针可以指向一个类型为返回值bool,参数为T& a,T& b的函数模板。这里具体的指向是比较两个参数的大小的模板,具体如下:
template<typename T> bool ascend(T &a, T &b)
{
return a < b ? true : false;
}
template<typename T> bool descend(T &a, T&b)
{
return a < b ? false : true;
}
分别是升序排列和和降序排列的时候需要用到的。具体使用方法:
int int_data[] = {4,2,8,1,7,3,2,9,12,5,6,45,23,34};
float f_data[] = {2.1,1.1,2.3,5.2, 6.0, 7.1,1.5,3.4, 2.3, 2.6, 1.9};
sort_demo<int>::sort(int_data, sizeof(int_data)/sizeof(int), ascend<int>);
print(int_data, sizeof(int_data) / sizeof(int));
sort_demo<int>::sort(int_data, sizeof(int_data) / sizeof(int), descend<int>);
print(int_data, sizeof(int_data) / sizeof(int));
sort_demo<float>::sort(f_data, sizeof(f_data)/sizeof(float), ascend<float>);
print(f_data, sizeof(f_data)/sizeof(float));
sort_demo<float>::sort(f_data, sizeof(f_data)/sizeof(float), descend<float>);
print(f_data, sizeof(f_data)/sizeof(float));
由于上面的类模板中的方法sort是static的所以可以使用sort_demo<类型>::sort访问。
自定义的类模板的类对象进行排序,这里以计算矩形面积的类模板。如下:
template<typename T>
class cal_size{
private:
T width;
T length;
public:
cal_size() :width(0), length(0){}
cal_size(T w, T l) :width(w), length(l){}
T cal_result(void)
{
return width*length;
}
};
其中的方法cal_result返回的就是矩形面积的大小。
对于这种类模板的使用方法:
cal_size<int> area[] = {cal_size<int>(2,4), cal_size<int>(1,4), cal_size<int>(3,2), cal_size<int>(2,4),cal_size<int>(3,3), cal_size<int>(5,2)};
int len = sizeof(area) / sizeof(cal_size<int>);
这个打印是使用函数模板print的特例化,类型是cal_size<int>:
template<> void print<cal_size<int>>(cal_size<int> data[], int len)
{
cout << "output data: ";
for (int i = 0; i < len; i++)
{
cout << data[i].cal_result() << " ";
}
cout << endl;
}
还有就是当两个类模板类型cal_size<int>在比较的时候,需要对‘<’‘>’重载运算符。
template<typename T>
bool operator < (cal_size<T>& area1, cal_size<T>& area2)
{
return area1.cal_result() > area2.cal_result() ? false : true;
}
template<typename T> bool operator > (cal_size<T>& area1, cal_size<T>& area2)
{
return area1.cal_result() > area2.cal_result() ? true : false;
}
完整的代码示例:
#include "stdafx.h"
#include <iostream>
#include <assert.h>
using namespace std;
template<typename T>
void print(T data[], int len)
{
cout << "output data: ";
for (int i = 0; i < len; i++)
{
cout << data[i] << " ";
}
cout << endl;
}
template<typename T> bool ascend(T &a, T &b)
{
return a < b ? true : false;
}
template<typename T> bool descend(T &a, T&b)
{
return a < b ? false : true;
}
template <typename T>
class sort_demo{
public:
static void sort(T *data, int len, bool (*compare)(T &a, T &b))
{
T temp;
assert(len >= 1);
cout << "len=" << len << " :";
for (int i = 0; i < len; i++)
{
for (int j = (i + 1); j < len; j++)
{
if (compare(data[i], data[j]))
{
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
}
};
template<typename T>
class cal_size{
private:
T width;
T length;
public:
cal_size() :width(0), length(0){}
cal_size(T w, T l) :width(w), length(l){}
T cal_result(void)
{
return width*length;
}
};
template<typename T>
bool operator < (cal_size<T>& area1, cal_size<T>& area2)
{
return area1.cal_result() > area2.cal_result() ? false : true;
}
template<typename T> bool operator > (cal_size<T>& area1, cal_size<T>& area2)
{
return area1.cal_result() > area2.cal_result() ? true : false;
}
template<> void print<cal_size<int>>(cal_size<int> data[], int len)
{
cout << "output data: ";
for (int i = 0; i < len; i++)
{
cout << data[i].cal_result() << " ";
}
cout << endl;
}
int main()
{
int int_data[] = {4,2,8,1,7,3,2,9,12,5,6,45,23,34};
float f_data[] = {2.1,1.1,2.3,5.2, 6.0, 7.1,1.5,3.4, 2.3, 2.6, 1.9};
sort_demo<int>::sort(int_data, sizeof(int_data)/sizeof(int), ascend<int>);
print(int_data, sizeof(int_data) / sizeof(int));
sort_demo<int>::sort(int_data, sizeof(int_data) / sizeof(int), descend<int>);
print(int_data, sizeof(int_data) / sizeof(int));
sort_demo<float>::sort(f_data, sizeof(f_data)/sizeof(float), ascend<float>);
print(f_data, sizeof(f_data)/sizeof(float));
sort_demo<float>::sort(f_data, sizeof(f_data)/sizeof(float), descend<float>);
print(f_data, sizeof(f_data)/sizeof(float));
cout << endl;
cout << "calculate rect area:";
cal_size<int> area[] = {cal_size<int>(2,4), cal_size<int>(1,4), cal_size<int>(3,2), cal_size<int>(2,4),cal_size<int>(3,3), cal_size<int>(5,2)};
int len = sizeof(area) / sizeof(cal_size<int>);
cout << "len=" << len << endl;
#if 1
sort_demo<cal_size<int>>::sort(area, sizeof(area)/sizeof(cal_size<int>), ascend<cal_size<int>>);
print(area, sizeof(area) / sizeof(cal_size<int>));
sort_demo<cal_size<int>>::sort(area, sizeof(area)/sizeof(cal_size<int>), descend<cal_size<int>>);
print(area, sizeof(area) / sizeof(cal_size<int>));
#endif
return 0;
}
代码运行的结果:
len=14 :output data: 45 34 23 12 9 8 7 6 5 4 3 2 2 1
len=14 :output data: 1 2 2 3 4 5 6 7 8 9 12 23 34 45
len=11 :output data: 7.1 6 5.2 3.4 2.6 2.3 2.3 2.1 1.9 1.5 1.1
len=11 :output data: 1.1 1.5 1.9 2.1 2.3 2.3 2.6 3.4 5.2 6 7.1
calculate rect area:len=6
len=6 :output data: 10 9 8 8 6 4
len=6 :output data: 4 6 8 8 9 10
请按任意键继续. . .