2012-04-19 99 views
3

我想实现的混合列表,所以例如我能做到这一点的问题:实现混合列表,使用模板

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; 
    } 

}; 

因为我不知道如何管理一个事实,即使用空指针,我真的不能投其所指向的数据是真实的class.With我的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++ 
} 

整个问题是,我不知道什么是我每次迭代,以元素的类型。 所以接下来可以是节点或节点或节点等......但如何解决这个问题?我将能够知道每个节点的类型,但我不能。 如何实现混合列表呢?

+2

不仅这不是很C++ - 惯用,但boost已经用'variant'和'any'实现了。你为什么试图重新发明轮子?可能最好的开始是看boost的'variant'实现,这样你就可以看到它们是如何在同一个空间中存储多种类型的。 – 2012-04-19 20:03:15

+1

@Mark B:他在学习:_“这是一个练习”_。 – orlp 2012-04-19 20:40:52

+0

@nightcracker:那么他应该看看Boost的实现,而不是要求我们重新创造它。 – 2012-04-19 22:07:08

回答

2

既然你不知道你正在存储什么类型的对象,我认为最简单的方法是将一个空指针存储到对象的分配副本。

接下来,您需要存储某种类型的标记以及对象。您也许可以使用由typeid返回的type_info对象的地址。

我看到一些其他问题,我不知道如何解决。要销毁列表,你需要每个元素的析构函数。也许你可以在创建元素的时候存储析构函数的地址,当你知道类型的时候。

+0

我不明白如何使用type_info。我曾尝试把两个字段:“type_info prev_type;”和“type_info next_type”,但我无法获得带有typeid的类型,该指令:“next_type = typeid(this)”被认为是语法错误。 – 2012-04-20 11:53:08