我正在尝试实现一个混合列表,所以例如我可以这样做:
mylist* l= new mylist();
l.push_back<int> (4);
l.push_back<string> ("hello");
这是一个练习因此不是使用其他库如boost的有效解决方案。 这个课程的方法很少:
template <class T>
class node
{
private:
void* next;
void* prev;
T data;
public:
node(T data)
{
this->data=data;
}
template <class R>
void link_to (node<R>& other)
{
next=&other;
other.prev=this;
}
};
因为我不知道如何管理使用void指针的事实,我无法真正地转换它的真实类指向的数据。使用dynamic_cast我应该尝试所有类型(节点,节点等...)所以这不是一个可以接受的解决方案。 因此,例如,如果我想打印一系列节点,我就无法做到:
int main(int argc, char** argv)
{
// for this example let's suppose that node fields were public
node<int> a(1),c(2);
node<std::string> b;
a.linkTo(b);
b.linkTo(c);
std::cout << a.data; // this is ok but I need to print also other nodes
// let's suppose that b and c were unreachable and that I want to reach them
// by iterating into the list
void* ptr=a.next; //public field
cout << ptr->data; //can't do that in C++
}
整个问题是我不知道我迭代的每个元素的类型。 所以接下来可以是节点或节点或节点等......但是如何解决这个问题呢?我将能够知道每个节点的类型,但我不能。 那么如何实现混合列表?
答案 0 :(得分:2)
由于您不知道存储的是哪种对象,我认为最简单的方法是将void指针存储到对象的已分配副本。
接下来,您需要将某种类型的标记与对象一起存储。您也许可以使用type_info
返回的typeid
对象的地址。
我看到其他一些我不知道如何解决的问题。要销毁列表,您需要为每个元素提供析构函数。当您知道类型时,也许您可以在元素创建期间存储析构函数的地址。