【原创】C++链表如何像Python List一样支持多种数据类型
用过Python的码友都知道,Python中List支持多种数据类型,如下面代码所示链表li内的数据类型可以是整数,同时也可以是字符串,当然也可以是其他数据类型。
1: >>> li = [1,2.5,"hello world"]
2: >>> li
3: [1, 2.5, 'hello world']
4: >>>
对于一个C++爱好者来说,不由得想C++中是不是也有类似的容器或者方法来实现一个链表内可以支持多种数据类型呢?答案是肯定的。boost内有现成的类可以使用,但是我们先不着急看这个现成类的使用,看看能用几种方法来实现?
基本思路是模板+继承。
实现方法一:
将链表节点中的数据类型template参数化(如下):
1: template<typename DataType>
2: class Node {
3: private:
4: DataType data;
5: ??? *next;
6: }
可是next节点的数据类型可能跟当前node的数据类型不同,那可怎么定义呢?不同的数据类型需要同样的接口,自然想到用“继承”的方法来解决,多说无益,上图,上代码:

1:
2: class NodeBase {
3: ...
4: private:
5: NodeBase *next;
6: };
7:
8: template<typename DataType>
9: class Node: public NodeBase {
10: ...
11: private:
12: DataType data;
13: };
这样,当需要存入多个数据类型时,就会有相应的节点类型产生(例如,我们有三种类型int, double, string):

测试代码如下:
1: class NodeBase {
2: friend class List;
3: friend ostream& operator<<(ostream &out, const List &list);
4: public:
5: NodeBase() : next(NULL) {}
6: virtual ~NodeBase() {}
7:
8: virtual void operator<<(ostream &out) = 0;
9:
10: private:
11: NodeBase *next;
12: };
13:
14: ///
15: ///template class to create Node type based on data type
16: ///
17: template<typename DataType>
18: class Node: public NodeBase {
19: friend class List;
20: public:
21: Node(const DataType &idata): data(idata){}
22:
23: virtual void operator<<(ostream &out)
24: {
25: out<<data;
26: }
27:
28: private:
29: DataType data;
30: };
31:
32: class List
33: {
34: friend ostream& operator<<(ostream &out, const List &list);
35: public:
36: List()
37: {
38: head = tail = NULL;
39: }
40: ~List()
41: {
42: for (; head;) {
43: NodeBase *next = head->next;
44: delete head;
45: head = next;
46: }
47: tail = NULL;
48: }
49:
50: ///
51: ///template function to add a new node
52: ///based on the input data type, to determine
53: ///the node type
54: ///
55: template <typename DataType>
56: void add(const DataType &data)
57: {
58: NodeBase *node = new Node<DataType>(data);
59: if (!tail) {
60: head = node;
61: }
62: else {
63: tail->next = node;
64: }
65: tail = node;
66: }
67:
68: private:
69: NodeBase *head, *tail;
70: };
71:
72: ///
73: ///test to output all datas in the input @a list
74: ///
75: ostream& operator<<(ostream &out, const List &list)
76: {
77: for (NodeBase *node = list.head; node; node = node->next)
78: {
79: node->operator<<(out);
80: out<<' ';
81: }
82: return out;
83: }
84:
85: ///
86: ///test a list support multiple data types just like Python
87: ///
88: int main()
89: {
90:
91: List *list = new List;
92:
93: list->add(1);
94: list->add(2.5);
95: list->add(string("hello world"));
96:
97: cout<<*list<<endl;
98:
99: delete list; list = NULL;
100: return 0;
101: }
实现方法二:
用一个抽象数据类型作为接口,直接上图:

1: class DataBase {
2: ...
3: };
4:
5: template <typename InnerType>
6: class Data : public DataBase {
7: public:
8: Data(const InnerType &idata) : innerData(idata) {}
9: ...
10: private:
11: InnerType innerData;
12: };
13:
14: class Node {
15: public:
16: template <typename InnerType>
17: Node(const InnerType &idata)
18: : data(new Data<InnerType>(idata)), next(NULL) {}
19: ~Node()
20: {
21: delete data; data = NULL;
22: }
23:
24: private:
25: DataBase *data;
26: Node *next;
27: };
测试代码如下:
1:
2: #include <iostream>
3:
4: using namespace std;
5:
6: class List;
7:
8: class DataBase {
9: public:
10: virtual ~DataBase() {}
11:
12: virtual void operator<<(ostream &out) = 0;
13: };
14:
15: template <typename InnerType>
16: class Data : public DataBase {
17: public:
18: Data(const InnerType &idata) : innerData(idata) {}
19:
20: virtual void operator<<(ostream &out)
21: {
22: out<<innerData;
23: }
24: private:
25: InnerType innerData;
26: };
27:
28: ///
29: ///template class to create Node type based on data type
30: ///
31: class Node {
32: friend class List;
33: friend ostream& operator<<(ostream &out, const List &list);
34: public:
35: template <typename InnerType>
36: Node(const InnerType &idata)
37: : data(new Data<InnerType>(idata)), next(NULL) {}
38: ~Node()
39: {
40: delete data; data = NULL;
41: }
42:
43: private:
44: DataBase *data;
45: Node *next;
46: };
47:
48: class List
49: {
50: friend ostream& operator<<(ostream &out, const List &list);
51: public:
52: List()
53: {
54: head = tail = NULL;
55: }
56: ~List()
57: {
58: for (; head;) {
59: Node *next = head->next;
60: delete head;
61: head = next;
62: }
63: tail = NULL;
64: }
65:
66: ///
67: ///template function to add a new node
68: ///based on the input data type, to determine
69: ///the node type
70: ///
71: template <typename InnerType>
72: void add(const InnerType &data)
73: {
74: Node *node = new Node(data);
75: if (!tail) {
76: head = node;
77: }
78: else {
79: tail->next = node;
80: }
81: tail = node;
82: }
83:
84: private:
85: Node *head, *tail;
86: };
87:
88: ///
89: ///test to output all datas in the input @a list
90: ///
91: ostream& operator<<(ostream &out, const List &list)
92: {
93: for (Node *node = list.head; node; node = node->next)
94: {
95: if (node->data) {
96: node->data->operator<<(out);
97: out<<' ';
98: }
99: }
100: return out;
101: }
102:
103: ///
104: ///test a list support multiple data types just like Python
105: ///
106: int main()
107: {
108:
109: List *list = new List;
110:
111: list->add(1);
112: list->add(2.5);
113: list->add(string("hello world"));
114:
115: cout<<*list<<endl;
116:
117: delete list; list = NULL;
118: return 0;
119: }
实现方法三:
用boost::any,关于它的介绍,这个博客不错:http://blog.csdn.net/hityct1/article/details/4186962,感兴趣的码友可以去深入了解。
参考文献
http://stackoverflow.com/questions/17528657/python-list-equivalent-in-c
http://www.cnblogs.com/kex1n/archive/2011/04/11/2013098.html
http://blog.csdn.net/debugm/article/details/8241759
http://www.360doc.com/content/14/0103/17/15099545_342367928.shtml
http://blog.csdn.net/hityct1/article/details/4186962
【原创】C++链表如何像Python List一样支持多种数据类型的更多相关文章
- python入门(8)数据类型和变量
python入门(8)数据类型和变量 数据类型 在Python中,能够直接处理的数据类型有以下几种: 整数 Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样 ...
- 我的Python学习之路 Python的输入输出与基本数据类型
*** python中的变量不需要事先声明再使用,而可以直接来一个变量名,后面一个赋值,接着一个数据值,如 hw = "hello python",相当于Python能智能的根据你 ...
- 用 Python 排序数据的多种方法
用 Python 排序数据的多种方法 目录 [Python HOWTOs系列]排序 Python 列表有内置就地排序的方法 list.sort(),此外还有一个内置的 sorted() 函数将一个可迭 ...
- 【转】让Souce Insight支持多种语言的语法高亮:Python,Ruby,ARM汇编,windows脚本文件(bat/batch),PPC,SQL,TCL,Delphi等
原文网址:http://www.crifan.com/source_insight_support_highlight_for_python_ruby_arm_batch_ppc_sql_tcl_de ...
- Python学习笔记:02数据类型
Python 数据类型 python中标准的数据类型有 基础类型 整型(长整型) 浮点型 复数型 布尔型 序列类型 字符串 列表 元组 字典 整型 整型和长整型并不严格区分,整型int的表达范围和计算 ...
- Python自动化开发-变量、数据类型和运算
一.变量 变量定义:Variables are used to store infomation to referrenced and manipulated in a computer progra ...
- Python第三天 序列 数据类型 数值 字符串 列表 元组 字典
Python第三天 序列 数据类型 数值 字符串 列表 元组 字典 数据类型数值字符串列表元组字典 序列序列:字符串.列表.元组序列的两个主要特点是索引操作符和切片操作符- 索引操作符让我 ...
- python学习日记(基础数据类型及其方法01)
数字 int 主要是用于计算的,常用的方法有一种 #既十进制数值用二进制表示时,最少使用的位数i = 3#3的ASCII为:0000 0011,即两位 s = i.bit_length() print ...
- python的6种基本数据类型--字典
python的6种基本数据类型--字典 字典 字典的定义与特性 字典是Python语言中唯一的映射类型. 定义:{key1:value1,key2:value2} 1.键与值用冒号":& ...
随机推荐
- Codeforces 712 D. Memory and Scores (DP+滚动数组+前缀和优化)
题目链接:http://codeforces.com/contest/712/problem/D A初始有一个分数a,B初始有一个分数b,有t轮比赛,每次比赛都可以取[-k, k]之间的数,问你最后A ...
- HDU3874Necklace(树状数组+离线操作)
此题的大意思说有一串珠子,每个珠子都有自己的欣赏值value,现在给你一串珠子每个的欣赏值,并给出一些询问,查询某个区间内部总欣赏值是多少,但是有一个约定就是如果这个区间内部有两个珠子的欣赏值是一样的 ...
- 手把手教你玩转SOCKET模型之重叠I/O篇(上)
“身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人.我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付 ...
- 监控SQL
http://www.cnblogs.com/downmoon/archive/2009/08/12/1544764.html
- cf754 B. Ilya and tic-tac-toe game
呵呵呵,这个题简直是一直在乱做,真是最近太弱了 #include<bits/stdc++.h> #define lowbit(x) x&(-x) #define LL long l ...
- MFC中 Invalidate() , InvalidateRect() , UpdateWindow(), Redrawwindow() 区别
1. void Invalidate( BOOL bErase = TRUE ); 该函数的作用是使整个窗口客户区无效.窗口的客户区无效意味着需要重绘,例如,如果一个被其它窗口遮住的窗口变成了前台窗口 ...
- Git版本管理:Windows下Git配置与使用指南
简要介绍:Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理. 一.安装 软件:msysGit-fullinstall-1.8.1.2 打开之后设置安装路径,默认为 ...
- 《Secrets of the JavaScript Ninja》:JavaScript 之运行时代码
最近,在阅读 jQuery 之父 John Resig 力作:Secrets of the JavaScript Ninja(JavaScript忍者秘籍).关于第九章提及的 JavaScript 之 ...
- mysql修改用户密码 新增用户
修改密码: mysql> grant all privileges on *.* to yongfu_b@'192.168.1.%' identified by 'my_password_new ...
- 【官方文档】Hadoop分布式文件系统:架构和设计
http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_design.html 引言 前提和设计目标 硬件错误 流式数据访问 大规模数据集 简单的一致性模型 “移动计 ...