《C++ primer plus》第十四章:C++的代码重用 学习笔记
来源:互联网 发布:武汉最新网络约车新规 编辑:程序博客网 时间:2024/05/21 12:49
《C++ primer plus》第十四章:C++的代码重用 学习笔记
这一章主要讲述了C++中的模板问题
1.valarray类的使用
valarray<int> v1;int gpa[4] = {1,2,3,4};valarray<int> v2; //sizeo 0valarray<int> v2(10); //size 10;valarray<int> v3(10,8);//size 8,each set to 10valarray<int> v4(gpa,4);//copy//valarray的一些函数sum, size, max, min, operator[];
2.成员初始化语法
一般来说,const数据成员必须用初始化语法,而非const不要求,但也可用
3.私有继承
派生类通过使用基类名和作用域解释操作符可以调用基类的方法
使用私有继承时,基类的公有成员和保护成员都变成了派生类的私有成员
使用派生继承时,基类的公有成员和保护成员都变成了派生类的保护成员
4.使用using重新定义访问权限
使用保护派生或私有派生时,如果想要在类外使用基类的方法:
一种方法是定义一个使用该基类方法的派生类方法
另一种方法是将函数调用包装在另一个函数的调用里,使用using声明,这样即使是私有声明也可以使用
(注意:第二种方法using声明只使用成员名,没有括号,函数特征表和返回值)
5.多重继承(MI)
(1)为了使从多个类派生出来的对象只有一个基类,使用虚基类,在类声明中使用virtual
class Singer:virtual public Worker{};class Waiter:virtual public Worker{};
使用虚基类时,C++禁止信息通过中间类自动传递给基类,因此,虚基类的构造函数应该是这样的:
SingWaiter(const Worker&a,int p,int v):Worker(a),Waiter(a,p),Singer(a,v){}
注意:这种做法对于非虚基类是不合法的
(2)MI可能造成函数的二义性,因此可以通过函数作用域解释操作符来确定那个函数,但是更好的方法是在派生类中
进行重定义,并指出要使用那个版本
6.类模板
(1)使用模板成员函数代替原有类的方法时,每个函数头都将以相同的模板声明开头:template <typename T>
同时,还需将Stack:: 改为Stack<Type>::
(2)模板不是函数,不能单独编译,必须与特定的模板实例化请求一起使用
7.深入讨论类模板
(1)正确使用指针堆栈
(2)递归使用类模板建立二维至多维数组
ArrayTP<int, 10> sums;//int[10]ArrayTP<double, 10> aves;//double[10]ArrayTP< ArrayTP<int,5>, 10> twodee;//int[10][5]
#include <iostream>#ifndef PAIR_H#define PAIR_Htemplate <typename T1,typename T2>class Pair{public:Pair(){}//~Pair();Pair(const T1& a1,const T2& b1){a = a1;b = b1;}T1 getfir()const{return a;}T2 getsec()const{return b;}private:T1 a;T2 b;};#endifusing namespace std;int main(){Pair<string,int> test("Max",12);cout << test.getfir() << ": " << test.getsec() << endl;}
(4)默认模板参数
template <typename T1,typename T2 = int> class Topo{};Topo<double,double> m1;//T1 is double,T2 is doubleTopo<double> m2;//T1 is double,T2 is int
<1>隐式实例化
<2>显式实例化
<3>显式具体化:用特定类型替换模板中的通用类型
例如,但模板使用>操作符进行比较时,对于数字,也许管用,但是对于字符串,就需要显示具体化。
template<> class Array(char *){......}
<4>部分具体化:给类型参数之一指定具体的类型
//general templatetemplate<class T1,class T2>class Pair{};//部分具体化template<class T1>class Pair{};
或者通过为指针提供特殊版本来部分具体化现有的模板
template<class T*>
//如果类型不是指针,函数将使用通用版本,如果提供的是指针,则编译器将使用指针具体化版本
(6)成员模板:模板可用做结构、类或模板类的成员
#include <iostream>using namespace std;template <typename T>class first{public:first(T t,int i):q(t),n(i){}//~first();void show()const{q.show();n.show();}private:template <typename U>class hold{public:hold(U u = 0){val = u;}//~hold();void show()const{cout << val << endl;}U getval()const{return val;}private:U val;};hold<T> q;hold<int> n;};int main(){first<double> guy(3.5,12);guy.show();return 0;}
(7)将模板用作参数
// stacktp.h -- a stack template#ifndef STACKTP_H_#define STACKTP_H_template <class Type>class Stack{private: enum {MAX = 10}; // constant specific to class Type items[MAX]; // holds stack items int top; // index for top stack itempublic: Stack(); bool isempty(); bool isfull(); bool push(const Type & item); // add item to stack bool pop(Type & item); // pop top into item};template <class Type>Stack<Type>::Stack(){ top = 0;}template <class Type>bool Stack<Type>::isempty(){ return top == 0;}template <class Type>bool Stack<Type>::isfull(){ return top == MAX;}template <class Type>bool Stack<Type>::push(const Type & item){ if (top < MAX) { items[top++] = item; return true; } else return false;}template <class Type>bool Stack<Type>::pop(Type & item){ if (top > 0) { item = items[--top]; return true; } else return false; }#endif
(8)模板类和友元
<1>模板类的非模板友元函数
template <class T>class Hasfriend{friend void counts();};//访问模板类参数时,必须指明具体化template <class T>class Hasfriend{friend void report(Hasfriend<T>&);//指明具体化};
#include <iostream>using namespace std;template <typename T>class Hasfriend{friend void show();friend void report(Hasfriend<T>& a);public:Hasfriend(const T& a):items(a){count++;}~Hasfriend(){count--;}private:T items;static int count;};template <typename T>int Hasfriend<T>::count = 0;void show(){cout << "Hasfriend<int> count: " << Hasfriend<int>::count << endl;cout << "Hasfriend<double> count: " << Hasfriend<double>::count << endl;}void report(Hasfriend<int>& a){cout << "Hasfriend<int> items: " << a.items << endl;}void report(Hasfriend<double> &a){cout << "Hasfriend<double> items: " << a.items << endl;}int main(){Hasfriend<int> a(12);Hasfriend<double> b(12.2);show();report(a);report(b);return 0;}
<2>模板类的约束模板的友元函数
修改前一个范例,是友元函数本身成为模板,分3步
A.在类定义前面声明每一个模板函数
template<typename T>void counts();template<typename T>void report(T &);
B.在函数中再次将模板声明为友元
template<typename TT>class Hasfriend{friend void counts<TT>();//对于report,<>可以为空,因为可以从函数参数中推断出模板的参数类型friend void report<>(Hasfriend<TT> &);};
C.为友元提供模板定义
template <typename T>void counts(){...}template<typename T>void report(T &hf){...}
//模板类的约束模板的友元函数
#include <iostream>using namespace std;template <typename T> void show();template <typename T> void report(T &a);template <typename T>class Hasfriend{public:Hasfriend(const T&a):items(a){count++;}~Hasfriend(){count--;}friend void show<T>();friend void report<>(Hasfriend<T>& a);private:T items;static int count;};template <typename T>int Hasfriend<T>::count = 0;template <typename T>void show(){cout << "Hasfriend count: " << Hasfriend<T>::count << endl;}template <typename T>void report(T& a){cout << a.items << endl;}int main(){Hasfriend<int> a(12);Hasfriend<int> b(13);Hasfriend<double> c(12.2);show<int>();show<double>();report(a);report(b);report(c);return 0;}
<3>模板类非约束模板的友元函数
template<typename T>class Manyfriend{template<typename T1,typename T2> friend void show2(T1 &,T2 &)};
//模板类非约束模板的友元函数
#include <iostream>using namespace std;template <typename T>class Hasfriend{public:Hasfriend(const T& i):items(i){}//~Hasfriend();template<typename T1,typename T2>friend void show(T1& a,T2& b);private:T items;};template<typename T1,typename T2>void show(T1& a,T2 &b){cout << a.items << " " << b.items << endl;}int main(){Hasfriend<int> a(12);Hasfriend<double> b(12.2);show(a,b);return 0;}
- 《C++ primer plus》第十四章:C++的代码重用 学习笔记
- 2012/2/3 《C++ Primer Plus》第十四章:C++中的代码重用 学习笔记
- c++primer第十四章c++代码重用(二)
- C++Primer学习笔记(代码重用)
- 《C++ Primer Plus(第六版)》(28)(第十四章 C++中的代码重用 笔记)
- C+Primer+Plus学习笔记-第二章
- C++Primer Plus学习笔记
- 《C Primer Plus》学习笔记
- 《C Primer Plus》学习笔记
- C Primer Plus 学习笔记
- C primer plus(第五版)编程练习第十四章
- c++primer plus第十四章-多重继承、模板类
- C Primer Plus(第五版) 第十四章 课后习题 4
- C Primer Plus(第五版) 第十四章 课后习题 6
- C Primer Plus(第五版) 第十四章 第八题
- C Primer Plus 第十四章 编程练习 1-11题
- C++Primer Plus(第六版) 第十四章 第一题
- C++Primer Plus(第六版) 第十四章 第五题
- 约瑟夫问题 mark
- 配置Sublime Text3编译汇编并高亮代码
- 【数据结构_树_Tree_0982】利用二叉树储存普通树的度
- 就地逆置带头结点的单链表
- DXP中关于PCB及原理绘制那些高级玩意总结
- 《C++ primer plus》第十四章:C++的代码重用 学习笔记
- Spark分析之BlockManager
- 第五章 语句
- L1-010. 比较大小
- 培训#1 欧拉函数&费马小定理(萌新瑟瑟发抖的来写一篇)
- Linux学习1
- 学习mac开发第十弹 Mac 选择照片,拍照。
- springmvc DispatcherServlet和拦截器详解
- LeetCode 171. Excel Sheet Column Number 题解 —— Java