【原创】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.键与值用冒号":& ...
随机推荐
- circle area
circle area Github 链接:传送门 本次作业要求 Create a program that asks for the radius of a circle and prints th ...
- Codeforces 100548F - Color (组合数+容斥)
题目链接:http://codeforces.com/gym/100548/attachments 有n个物品 m种颜色,要求你只用k种颜色,且相邻物品的颜色不能相同,问你有多少种方案. 从m种颜色选 ...
- UVaLive 6602 Counting Lattice Squares (找规律)
题意:给定一个n*m的矩阵,问你里面有几面积为奇数的正方形. 析:首先能知道的是,大的矩阵是包括小的矩阵的,而且面积为奇数,我们只要考虑恰好在边界上的正方形即可,画几个看看就知道了,如果是3*3的有3 ...
- 建立ODBC数据源(基于windows)
1. win+r 2. control 3. 打开数据源 4. 点击添加 5. 选择Oracle in OraClient11g_home1 ,点击完成 6. 填写,查看具体参数信息点击Help 7. ...
- LRESULT与wParam和lParam的问题
在微软vc提供的头文件中有定义在winnt.h中typedef long LONG;在windef.h中typedef LONG LRESULT; 所以LRESULT就是long,也就是长整形之所以取 ...
- UVa 10004:Bicoloring
这道题要我们判断所给图是否可以用两种颜色进行染色,即"二染色“.已知所给图一定是强连通图. 分析之: 若图中无回路,则该图是一棵树,一定可以二染色. 若图中有回路,但回路有偶数个节点,仍然可 ...
- GetWindowThreadProcessId用法(转)
函数功能:该函数返回创建指定窗口线程的标识和创建窗口的进程的标识符,后一项是可选的. 函数原型:DWORD GetWindowThreadProcessld(HWND hwnd,LPDWORD lpd ...
- 网页上的JS call Unity3d里的function——SendMessage
注意: sendmessage只可以从网页发信息到unity游戏里,但是没有返回值 只可以发布三种类型的data,不可以其他复杂的强类型 发信息的时不会做编译检测 SendMessage Workfl ...
- NLog使用总结
一.代码调用方式: public static readonly Logger Logger = LogManager.GetCurrentClassLogger(); Logger .Trac ...
- 【转】HTTP HEAD
原文出自:http://kb.cnblogs.com/page/92320/ HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议.HTTP协议采用 ...