First, goal
Implement a linked list, where the element type can be different.
Second, the idea
[Idea one]
In the node, the data is stored with the common numerals, and the next node is directed by the VOID * pointer, and the data type of this node is recorded in the node.
0000 Enum type {int, char, string}; 0001 struct node {0002 type nodetype; 0003 union {0004 int rtData; 0005 char charData; 0006 string strdata; 0007} value; 0008 void * next; 0009};
Every element of the linked list is actually the same.
[Idea 2]
Design an abstract node class, node of different data types to inherit it. The pointer to the base class can point to each derived class.
[Three Ideas]
The above two ideas require data types known, difficult to add new types. So I change the [Idea 2], and write the derived class with the template.
Third, code
0000 #ifndef HETERLIST_H0001 #define HETERLIST_H0002 #include 0003 #include 0004 0005 struct Pointer {0006 // when printing data for traversing nodes 0007 virtual std :: ostream & printData (std :: ostream &) = 0; 0008 // Judging whether the two knots are judged when the two knots are equal to 0009 Virtual Bool Operator == (Pointer *) = 0; 0010}; 0011 0012 Template 0013 Class Node: Public Pointer {0014 T_Data; 0015 public: 0016 node (): _ data (0) {} 0017 Node (t data): _ data (data) {} 0018 Virtual st: ostream & printdata (std :: ostream& out) 0019 {OUT << _data; return out;} 0020 Virtual Bool Operator == (POINTER * P) 0021 {0022 IF (Node * PP = Dynamic_Cast *> (P)) 0023 return_data == pp-> getData (); 0024 else0025 Return False ; 0026} 0027 const {return_data;} 0028 void setdata (t D) {data = D;} 0029 virtual ~ node ()}; 0030}; 0031 0032 std :: ostream & operator << STD: : Ostream & Out, Pointer * P) 0033 {0034 Return P-> PrintData (OUT); 0035} 0036 0037 0038 TypedEf st :: list heterlist; 0039 typef std :: list :: itemator HLI ; 0040 0041 #ENDIF / / HETERLIST_H
0000 #include 0001 #include 0002 #include 0003 #include "heterlist.h" 0004 using namespace std; 0005 0006 // Customize a simple class for testing if the heterogeneous list is You can insert a custom class 0007 // is visible from the definition of heterogenes, require custom class overload Operator << and == 0008 class classnode {0009 string _str; 0010 public: 0011 classnode (string s = 0): _ Str s) {} 0012 string getData () const {return _str;} 0013 ostream & printdata (ostream & out) {out << _Str; return out;} 0014 bool operator == (classnode n) {return_str == n.Getdata } 0015}; 0016 // Avoid using friends, keep the encapsulation 0017 ostream & operator << (Ostream & Out, ClassNode * n) 0018 {0019 returnit N-> PrintData (out); 0020} 0021 0022 int Main ) 0023 {0024 // Define a heterogeneous table TestList0025 heterlist test1156 // For testing, three different "quality" nodes are defined. In fact, since the Template, 0027 // This heterogene is inserted into any type of node.
But there is a prerequisite: If it is a class 0028 //, this class requires overloading Operator << and == 0029 Node * intNode; 0030 Node * charnode; 0031 node * usernode; 0032 0033 ClassNode; 0034 0035 // Insert INT type element 0036 for (int i = 0; i <3; i) {0037 intNode = new node (i); 0038 TestList.push_back (intNode) ; 0039} 0040 // Insert Char type element 0041 for (CHAR C = 'a'; c <'c' 1; c) {0042 charnode = new node (c); 0043 Testlist.push_back Charnode); 0044} 0045 0046 // Insert a custom class 0047 for (int i = 0; i <3; i) {0048 string s = "my class"; 0049 s = char (i 48); // '0' is ACII codes 480050 tempClassNode = new classNode (s); 0051 userNode = new Node (tempClassNode); 0052 testList.push_back (userNode); 0053} 0054 0055 cout << "traverse the list: "<< endl; 0056 for (HLI i = testlist.begin (); i! = Test.end (); i) {0057 cout << * i << endl ; 0058} 0059 // Destroy heterogeneous list.