《深入实践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++的特性, 将越来越多的问题和事物抽象成对象时, 我们不难发现:很多对象都具有共性. 比如 数值可以增加.减少:字符串也可以增加减少. 它们的动作是相似的, 只是对象的类型不同 ...
随机推荐
- Nginx反向代理设置header
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- MySQL-插入更新 ON DUPLICATE KEY UPDATE
向数据库中插入一条记录,若该数据的主键值(UNIQUE KEY)已经在表中存在,则执行后面的 UPDATE 操作.否则执行前面的 INSERT 操作. 测试表结构 CREATE TABLE `flum ...
- CORS和jsonp实现跨域请求
同源策略:所谓同源是指,域名,协议,端口相同,它是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略.当浏览器同时打开两个tab页面(两个不同服务器 ...
- 【log4j】log4j.properties 文件示例
# 下面的文件内容是写程序长期要用的,放在这里留个底#Output information(higher than INFO) to stdout and file.info/debug/error ...
- Docker镜像搭建ubuntu下samba目录共享
第一种方法:(未使用) yum install docker // 下载镜像 docker pull dperson/samba // 启动镜像,具体看文档,但重要的配置是以下的注释 docker r ...
- easyU之tabs选项卡
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- ping指定IP的指定端口号
ping是简单的测试网络连接情况的小工具,对于一般用户很实用,但是ping有个缺点就是,不能指定端口 tcping命令是针对tcp监控的,也可以看到ping值,即使源地址禁ping也可以通过tcpin ...
- Java中验证编码格式的一种方法
package forlittlecatty; import java.io.File; import java.io.FileInputStream; import java.io.IOExcept ...
- python之selenium三种等待方法
前提: 我们在做Web自动化时,有的时候要等待元素加载出来,才能操作,不然会报错 1.强制等待 2.隐式等待 3.显示等待 内容: 一,强制等待 这个比较简单,就是利用time模块的sleep的方法来 ...
- 配置nova服务使用ceph作为后端存储
在ceph监视器上执行 1.创建pool池 为nova服务创建pool池(因为我只有一个OSD节点,所以要将副本数设置为1) ceph osd pool create nova-vms 32 ceph ...