链接列表静态类成员

时间:2017-03-05 09:45:36

标签: c++ pointers static linked-list

所以,首先我想说我正在做这个学习,这就是为什么我没有使用标准库容器。

我有一个代表Qt Ui中的小部件的类。可以删除这些小部件,也可以在列表末尾添加新小部件,这就是它们在链表中的原因。该课程如下:

class Item
{
    static Item* first_item;
    static Item* last_item;
    Item* prev_item;
    Item* next_item;

    public:
    Item(MainWindow*, bool);
    ~Item();              
} 

我的问题是,如果我想拥有这种类型的多个链表(比如两个不同的小部件列表),那么first_itemlast_item节点的静态指针将是相同的列表,这很糟糕。我有想法将第一个和最后一个指针作为构造函数参数,因此新创建的Item知道它属于哪个列表。

这对我来说似乎很难看,有没有更好的方法呢?

3 个答案:

答案 0 :(得分:1)

你可以在不声明static的情况下进行检查吗?我认为static是个问题。 static成员是“每班一个”。我认为更好的方法是在构造函数中将它们初始化为值(也可以指定默认值)。

阅读本文以了解有关static关键字的更多信息:http://www.cprogramming.com/tutorial/statickeyword.html

可能相关的主题:C++ class with static pointerInitializing a static pointer in C++

答案 1 :(得分:0)

拥有指向列表的第一个的属性可能会导致您遇到问题。由于第一个可能会在以后更改,因此每次都必须更新该列表中所有元素的第一个指针。

如果您有多个列表,则存储第一个指针列表(列表列表):

// Each element in the list is head of a linked list    
std::vector<Item*> itemLists; 

此处的向量用于简化。您可以轻松地为“项目列表”列表声明另一个类,例如:

class List
{
    Item *first;
    //Item *last; // you may also want to know the last.
    List *nextList, *prevList;
};

顺便说一句,因为它是一个双向链表,你可以创建一个函数来返回每个项的第一个和最后一个:

Item *first()
{
   if(prev_item != NULL)
       return prev_item->first();
   return this;
}

Item *last()
{
   if(next_item != NULL)
      return next_item->last();
   return this;
} 

总之,不要使用静态属性。另外一个元素不需要首先知道它(然而,它可以通过一个简单的函数来实现它的第一个)。这将浪费记忆力。使用列表的外部类需要知道第一个(和/或最后一个,取决于您的需要)。

答案 2 :(得分:0)

最简单的解决方案是分离列表本身(需要知道第一个和最后一个项目,以及项目(不是)。

class List
{
    class Item  // This is private to List, so List automatically has access
                // to its internals.
    {
        Item* prev_item;
        Item* next_item;
        T Value;          // Presumably each item in the list has some sort
                          // of value;
    }
    Item* first_item;
    Item* last_item;
public:
    List(...);  // Constructor as appropriate
    ~List();
    List(const List& rhs) = delete;            // Need a copy constructor 
    List& operator=(const List& rhs) = delete; // and copy assignment operator.
} 

如果您希望能够复制或分配列表,则需要实际执行相应的功能,而不是= delete

如果您希望每个Item都记住它所属的List,您可以将引用添加回所有者。

class List
{
    class Item  // This is private to List, so List automatically has access
                // to its internals.
    {
        Item* prev_item;
        Item* next_item;
        T value;          // Presumably each item in the list has some sort
                          // of value;

        const List& owner;// Back reference.
        Item(const List& owner_) : owner(owner_) {}
    }
    Item* first_item;
    Item* last_item;
public:
    List(...);  // Constructor as appropriate
    List(const List& rhs) = delete;
    List& operator=(const List& rhs) = delete;
    ~List();
} 

当然,如果Item记得它的拥有者,那么复制和分配就会变得更加棘手。