本文共 5694 字,大约阅读时间需要 18 分钟。
意思就是类模板中吧类模板当做成员函数或者类成员
直接上代码吧
#includeusing std::cout;using std::cin;using std::endl;template class beta{ private: template class hold { private: V val; public: shold(V v = 0) : val(v) {} void show() const {cout << val << endl;} V Value() const {return val;} }; hold q; hold n; public: beta(T t, int i) : q(t), n(i) {} template U blab(U u, T t){return (n.Value() + q.Value()) * u /t;} void Show() const { q.show(); n.show();}};int main(){ beta guy(3.5, 3); cout << "T was set to double\n"; guy.Show(); cout << "V was set to T, which is double, then V was set to int\n"; cout << guy.blab(10, 2.3) << endl; cout << "U was set to int\n"; cout << guy.blab(10.0, 2.3) << endl; cout << "U was set to double\n"; cout << "Done\n"; return 0;}
C++允许外部定义成员模板。但不是所有的编译器都支持。 如果不支持的话就算了 支持的话可以这么写:
将模板用于参数:
先上代码在说话
stacktp.h
#ifndef STACKTP_H_#define STACKTP_H_templateclass Stack{ private: enum {MAX = 10}; Type items[MAX]; int top; public: Stack(); bool isempty(); bool isfull(); bool push(const Type & item); bool pop(Type & item);};template Stack ::Stack(){ top = 0;}template bool Stack ::isempty(){ return top == 0;}template bool Stack ::isfull(){ return top == MAX;}template bool Stack ::push(const Type & item){ if (top < MAX) { items[top++] = item; return true; } else { return false; }}template bool Stack ::pop(Type & item){ if (top > 0) { item = items[--top]; return true; } else return false;}#endif
tempparm.cpp
#include#include "stacktp.h"template class Thing>class Crab{ private: Thing s1; Thing s2; public: Crab() {}; bool push(int a, double x) {return s1.push(a) && s2.push(x);} bool pop(int & a, double & x) {return s1.pop(a) && s2.pop(x);}};int main() { using std::cout; using std::cin; using std::endl;// 这时候 Thing形参就是 模板Stack类型 在默认构造函数的时候就生成int型的Stack模板和double型的Stack模板 Crab nebula; int ni; double nb; cout << "Enter int double pairs, such as 4 3.5 (0 0 to end):\n"; while(cin >> ni >> nb && ni > 0 && nb > 0) { if (!nebula.push(ni, nb)) break; } while (nebula.pop(ni, nb)) cout << ni << ", " < << endl; cout << "Done.\n"; return 0;}
运行结果:
模板类和友元:
模板类可以有友元, 但是有3种友元
1. 非模板友元
2. 约束模板友元
3.非约束模板友元
一个一个来
非模板友元
templateclass A{ public: friend void counts();}
counts()是模板所有实例化对象的友元。 这是不带参数的例子。它可以访问全局对象,可以使用全局指针访问的费全局对象。可以创建自己的对象。 可以访问独立于对象的模板类的静态数据成员。
那如果要带参数呢 而且是要带模板类参数呢?
但需要指明特定类型的对象 比如:
templateclass A{ public: friend void counts(A &);}
这样将counts将称为A<T>类的友元。
程序示例:
#includeusing std::cout;using std::endl;template class HasFriend{ private: T item; static int ct; public: HasFriend(const T & i) : item(i) {ct++;} ~HasFriend() {ct--;} friend void counts(); friend void reports(HasFriend &);};template int HasFriend ::ct = 0;void counts(){ cout << "int count: " << HasFriend ::ct << "; "; cout << "double count: " << HasFriend ::ct << endl;}void reports(HasFriend & hf){ cout << "HasFriend : " << hf.item << endl;}void reports(HasFriend & hf){ cout << "HasFriend : " << hf.item << endl;}int main(){ cout << "No objects delared: "; counts(); HasFriend hfi1(10); cout << "After hfil declared: "; counts(); HasFriend hfi2(20); cout << "After hfi2 declared: "; counts(); HasFriend hfdb(10.5); cout << "AFter hfdb delared: "; counts(); reports(hfi1); reports(hfi2); reports(hfdb); return 0;}
运行结果
2.约束模板友元函数
就是把友元函数先声明为函数模板 然后在类模板中定义的是该函数模板
程序示例:
#includeusing std::cout;using std::endl;template void counts();template void report(T &);template class HasFriendT{ private: TT item; static int ct; public: HasFriendT(const TT & i) : item(i) {ct++;} ~HasFriendT() {ct--;} friend void counts (); friend void report<>(HasFriendT &);};template int HasFriendT ::ct = 0;template void counts(){ cout << "template size: " << sizeof(HasFriendT ) << "; "; cout << "template counts(); " << HasFriendT ::ct << endl;}template void report(T & hf){ cout << hf.item << endl;}int main(){ counts (); HasFriendT hfi1(10); HasFriendT hfi2(20); HasFriendT hfdb(10.5); report(hfi1); report(hfi2); report(hfdb); cout << "counts () output:\n"; counts (); cout << "counts () output:\n"; counts (); return 0;}
运行结果
3.非约束模板友元函数
模板类型放开 ,不用跟着模板类型走:
示例:
#includeusing std::cout;using std::cin;template class ManyFriend{ private: T item; public: ManyFriend(const T & i) : item(i) {} template friend void show2(C &, D &);};template void show2(C & c, D & d){ cout << c.item << ", " << d.item << '\n';}int main(){ ManyFriend hfi1(10); ManyFriend hfi2(20); ManyFriend hfdb(10.5); cout << "hfi1, hfi2: "; show2(hfi1, hfi2); cout << "hfdb, hfi2: "; show2(hfdb, hfi2); return 0;}
运行结果
大体区别就是
非模板的友元: 没有跟着哪个类 就是跟某个实例对象友元。
约束模板函数: 就是跟某个类型的模板关联。
非约束模板函数: 不限制某个类型的模板, 因为定义了另外的两个模板参数。所以可以传入不同类型的模板作为参数。
然后目前来说。好像没啥卵用。
模板别名:
可以这样定义别名:
typedef std::arrayarri;
C++11 可以这样:
template<typename T>
using arrtype = std::array<T, 12>;
然后可以这么干:
arrtype<double> gallons;
arrtype<int> days; == array<int , 12>
这种定义别名的方式也适用于非模板
优点: 可读性更强,因为它让类型名和类型信息更清晰。
总结:
第十四章 真 • 完结
转载地址:http://gnepi.baihongyu.com/