《深入实践C++模板编程》之二——模板类
#include <stdexcept> template<typename T> class my_stack; template<typename T>
class list_node
{
T value;
list_node *next; list_node(T const &v, list_node *n) :
value(v), next(n){} friend class my_stack<T>;
}; template<typename T>
class my_stack
{
typedef list_node<T> node_type;
node_type *head; my_stack operator=(my_stack const&);
my_stack(my_stack const &s){} public:
my_stack() :head(){}
~my_stack()
{
while (!empty())
pop();
} bool empty(){ return head == ; }
T const& top() const throw(std::runtime_error)
{
if (empty())
{
throw std::runtime_error("Stack is empty");
}
return head->value;
} void push(T const &v)
{
head = new node_type(v, head);
} void pop();
}; template<typename T>//类成员函数的实现同样要放在和类声明相同的头文件里
void my_stack<T>::pop()
{
if (head)
{
node_type* tmp = head;
head = head->next;
delete tmp;
}
}
template<typename T>
class count_stack : public my_stack<T>
{
typedef my_stack<T> base_type;
unsigned size; public:
count_stack() :base_type(), size(){}
void push(T const &v)
{
base_type::push(v);
size++;
} void pop()
{
if (size > )
{
base_type::pop();
size--;
}
} unsigned getSize() const { return size; }
};
如果是普通类以模板实例为基类,需要为基类模板给定明确的模板参数值。例如,
template<typename T, typename N>
struct hetero_node
{
T value;
N* next;
hetero_node(T const &v, N *n) :value(v), next(n){}
}; template<typename T, typename N>
hetero_node<T, N>* push(T const &v, N *n)
{
return new hetero_node<T, N>(v, n);
} template<typename T, typename N>
N* pop(hetero_node<T, N> *head)
{
N *next = head->next;
delete head;
return next;
}
typedef hetero_node<int, void> node0;
typedef hetero_node<char, node0> node1;
typedef hetero_node<std::string, node1> node2; node2 *p2 = push(std::string("Awesome"),
push('w',
push(, (void*)NULL))); pop(pop(pop(p2)));
template<typename T, typename N>
struct tuple
{
T value;
N next;
tuple(T const &v, N const &n) :value(v), next(n){}
}; template<typename T, typename N>
tuple<T, N> push(T const &v, N const &n)
{
return tuple<T, N>(v, n);
} typedef tuple<int, char> tuple0;
typedef tuple<float, tuple0> tuple1;
typedef tuple<std::string, tuple1> tuple2; tuple2 t = push(std::string("test"),
push(1.0f,
push(, 'a')));
template<typename T0, typename T1, typename T2>
struct tuple3
{
T0 v0;
T1 v1;
T2 v2;
tuple3(T0 const &_v0, T1 const & _v1, T2 const & _v2) :
v0(_v0), v1(_v1), v2(_v2){}
};
总结:异质链表摆脱具体数据类型的束缚。
template<typename T>
void my_stack<T>::pop()
{
if (head)
{
node_type* tmp = head;
head = head->next;
delete tmp;
}
}
struct normal_class
{
int value;
template<typename T>
void set(T const &v)
{
value = int(v);
}
};
template<typename N>
struct a_class_template
{
N value; template<typename T>
void set(T const& v)
{
value = N(v);
} template<typename T>
T get();
}; template<typename N> template<typename T>
T a_class_template<N>::get()
{
return T(value);
}
template<typename T>
struct the_class
{
static int id;
the_class(){ id++; }
}; template<typename T> int the_class<T>::id = ; void call1()
{
the_class<int> c;
printf("static id:%d\n", c.id);
} void call2()
{
the_class<int> c;
printf("static id:%d\n", c.id);
}
《深入实践C++模板编程》之二——模板类的更多相关文章
- 《深入实践C++模板编程》之三——模板参数类型详解
非类型模板参数 和 模板型模板参数 整数以及枚举类型:指向对象或者函数的指针:对对象或函数的引用:指向对象成员的指针.统称为非类型模板参数. 模板型模板参数,是指模板参数还可以是一个模板. 1.整 ...
- JavaScript 面向对象的编程(二) 类的封装
类的定义 方式一 var Book = function(id, name, price){ //私有属性,外部不能直接访问 var num = 1; //私有方法, function checkId ...
- Scala 编程(二)类和对象
类,字段和方法 类是对象的蓝图.一旦定义了类,就可以用关键字new从类的蓝图里创建对象,类的定义: class ChecksumAccumulator { // class definition go ...
- Django模板的继承与模板的导入
目录 一:模版的继承 1.什么是模板继承? 2.使用继承流程原理 3.模板继承语法 二:模板的继承使用 1.案例需求 2.总结模板继承 三:模版的导入 1.模板导入 2.模板导入格式 3.模板导入使用 ...
- 《深入实践C++模板编程》之四——特例
1. 所谓模板特例,是针对符合某种条件的模板参数值集合另外声明的模板实现变体. template<typename T> class my_vector; template<> ...
- 《深入实践C++模板编程》之一——Hello模板
1.通过一个简单的例子来理解模板的用途: 模板为不同类型的数据生成操作相同或相似的函数. 弱语言如Python,可以使用一种函数来应对各种类型,但是C++就不得不为不同的类型编写相似的函数.模板的作用 ...
- C++ 11可变参数接口设计在模板编程中应用的一点点总结
概述 本人对模板编程的应用并非很深,若要用一句话总结我个人对模板编程的理解,我想说的是:模板编程是对类定义的弱化. 如何理解“类定义的弱化”? 一个完整的类有如下几部分组成: 类的名称: 类的成员变量 ...
- C++模板编程中只特化模板类的一个成员函数
模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多数成员函数的功能可能是一模一样的,特化时我们可能只需要重新实现1.2个成员函数即可.在这种情况下,如果全 ...
- C++之模板编程
当我们越来越多的使用C++的特性, 将越来越多的问题和事物抽象成对象时, 我们不难发现:很多对象都具有共性. 比如 数值可以增加.减少:字符串也可以增加减少. 它们的动作是相似的, 只是对象的类型不同 ...
随机推荐
- shell脚本编程进阶
在linux shell中,通常我们将一些命令写在一个文件中就算是一个shell脚本了,但是如果需要执行更为复杂的逻辑判断,我们就需要使用流程控制语句来支持了.所谓流程控制既是通过使用流程控制语句对程 ...
- Linux系统下关闭与启动Oracle11g的顺序与命令
关闭: 1.关EM:[oracle@localhost ~] emctl stop dbconsole 2.关监听:[oracle@localhost ~] lsnrctl stop 3.关数据库:S ...
- Qt串口通信专题教程
查看以前的教程:Qt编写串口通信程序全程图文讲解 查看Wincom和Lincom介绍:Qt跨平台串口通信软件Wincom与Lincom 下载软件,文档和源码:资源下载 ——————————————20 ...
- 前端知识点回顾——Javascript篇(三)
数组的冒泡.选择和插入排序法 冒泡排序法(从小到大) function bubble(arr){ for(let i = 0 ;i<arr.length-1;i++){ for(let j = ...
- MS SQL 数据类型转换
MS SQL 转换数据类型 select cast(列A as int) 列A select convert(int,列A) 列A --转字符串为int select len(ltrim(str('数 ...
- leetcode39 组合总和
这道题想到的就是dfs,在累加的和大于或等于target时到达递归树的终点. 代码如下: class Solution { public: vector<vector<int>> ...
- nginx 反向代理实现负载均衡*配置实战
重要点: 1配置反向代理多虚拟主机节点服务器 2经过反向代理后的节点服务器记录用户IP 3与反向代理配置相关的更多参数说明 4根据URL目录地址转发 (1)根据URL中的目录地址实现代理转发(动静分离 ...
- Delphi通过ADO读写数据库
ADO是一种程序对象,用于表示用户数据库中的数据结构和所包含的数据. ADO (ActiveX Data Objects,ActiveX数据对象)是Microsoft提出的应用程序接口(API)用以实 ...
- Qt在控制台输出中文的解决办法(转载)
转载网址:https://blog.csdn.net/qq_22512533/article/details/75408984 按下快捷键Win+R,输入regedit打开注册变编辑器,依次找到 HK ...
- powerDesigner关联数据库显示中文注释
最近使用powerdesigner,遇到些问题,记录一下[安装过程就略过了] 一.安装odbc驱动 分享下驱动,百度网盘链接:https://pan.baidu.com/s/1UYPq_PEQkDOJ ...