赞
踩
往期地址:
本期主题:
STL编程之模板template
STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库,它被容纳于C++标准程序库(C++ Standard Library)中。
从逻辑层次来看,在STL中体现了泛型化程序设计的思想(generic programming),引入了诸多新的名词,比如像需求(requirements),概念(concept),模型(model),容器(container),算法(algorithmn),迭代子(iterator)等。与OOP(object-oriented programming)中的多态(polymorphism)一样,泛型也是一种软件的复用技术。
一次性引入了这么多名词,大家不用紧张,我们会用一个简单的例子来引出这些东西。
模板是泛型编程的基础,简单理解泛型编程就像c语言中我们经常使用的函数指针
//模板函数的使用方法
template <typename type> ret-type func-name(param list)
{
}
看一个简单的例子,我们现在想实现一个函数,函数的作用是找出最大值,如果用传统的方法,当比较的数据是float型时,需要实现一个函数原型,比较的数据是int型时,又需要实现一个函数原型,这样十分的不灵活,因此我们可以使用模板编程的方法。
include <iostream> using namespace std; /* 模板的使用例子: 1.创建一个模板方法用来实现不同参数类型的加法,例如add(int , int)以及add(float float); 2.如果用原来的方法,则每个类型都需要单独实现一个函数,效率太低,因此可考虑使用模板; 3.模板是泛型编程的基础,泛型编程指的是不指定具体类型的编程,与类型无关 4.模板编程的方法: template <typename type> ret-type func-name(param list) */ template <typename T> T find_max(T& a, T& b) { T temp; if (a < b) temp = b; else temp = a; return temp; } int main(void) { int a = 1; int b = 2; cout << "the int max is " << find_max(a, b) << endl; float p1 = 8.7; float p2 = 3.3; cout << "the float max is " << find_max(p1, p2) << endl; return 0; } gary@ubuntu:~/workspaces/cpp_study/5.1.template$ ./app the int max is 2 the float max is 8.7
就像我们定义函数模板一样,我们也可以定义类模板
template <typename type> class class-name {
}
例如我们现在定义一个模板类test,这个类中的两个私有成员都是模板,没有被实例化
/* 定义一个模板类,类中的方法也使用模板来进行实现 在最后调用的时候去确定template类到底代表着什么 */ template <typename T> class test { private: T a; T b; public: T find_max(void); void set_val(T, T); }; //这句代码相对于是两个部分,前面的template <typename T>是代表对类型T的定义,告诉编译器T是一个模板; //第二部分,void代表return type, test<T>代表test类以及T定义在test类中 template <typename T> void test<T>::set_val(T a, T b) { this->a = a; this->b = b; } template <typename T> T test<T>::find_max(void) { T temp; if (a < b) temp = b; else temp = a; cout << "find_max is " << temp << endl; return temp; } int main(void) { int a = 1; int b = 2; test<int> p1; //在main中最后运行时,需要告诉编译器T的类代表啥; p1.set_val(1, 2); p1.find_max(); test<float> p2; p2.set_val(1.2, 2.1); p2.find_max(); return 0; } gary@ubuntu:~/workspaces/cpp_study/5.1.template$ ./app find_max is 2 find_max is 2.1
我们可以先回忆一下,当不使用模板时,友元函数是如何表达的
直接在类中定义时,用friend关键词表明友元函数
class xxx
{
private:
public:
friend void func(const xxx& p); //一般传入该类型的引用作为参数,这样才能访问该类型里的私有成员
}
使用模板友元函数的实际例子:
#include <iostream> #include <string> //该文件是使用模板类型的友元函数 using namespace std; template <typename T> class People; template <typename T> void print_age(const People<T>& p); /* */ template <typename T> class People { private: T age; public: People(){}; People(T a):age(a){}; friend void print_age<T>(const People<T>& p); //声明的函数名字中的这个T是必须的,如果不添加会报错: /* 3.1.5.template_friend.cpp:21:45: warning: friend declaration ‘void print_age(const People<T>&)’ declares a non-template function [-Wnon-template-friend] friend void print_age(const People<T>& p); ^ 3.1.5.template_friend.cpp:21:45: note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) /tmp/ccWpihzK.o: In function `main': */ }; template <typename T> void print_age(const People<T>& p) { cout << "age = " << p.age<< endl; } int main(void) { People<int> a(10); print_age(a); return 0; }
总结:
注意函数名后面的T
#include <iostream> #include <string> //该文件是定义一个使用运算符重载的模板 using namespace std; /* */ template <typename T> class test { private: T age; public: //T find_max(void); void print_test(void); test(){}; test(T a):age(a){}; //如果没有这个模板T的话,运算符重载的定义应该是 //test operator+(test &) 有了T之后变成了 test<T> operator+(test<T> &other); }; //template <typename T>告诉编译器T是一个变量 //第一个test<T>是返回值类型,第二个test<T>是代表属于这个类 template <typename T> test<T> test<T>::operator+(test<T> &other) { test<T> tmp; tmp.age = this->age + other.age; return tmp; } template <typename T> void test<T>::print_test(void) { cout << "age = " << this->age << endl; } int main(void) { test<int> a(13); test<int> b(12); test<int> c(0); c=a+b; c.print_test(); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。