静的単一リンクリストを達成

 

使用シナリオ:
頻繁欠失データ要素
の固定のデータ要素の最大数

 

欠陥の単一のリスト
- トリガーが
  頻繁に追加、削除データ要素オブジェクト単一のリストの使用を長期
- 起こりそうな結果を
  ゆっくり実行するためのシステム原因、メモリの断片化のヒープ領域に大量

説明:

リストに単一のデータ要素を追加すると、彼らは、ビューの手続きの点から、何の問題もなく、そうするヒープ領域にノードジャンクションを作成しますが、長い時間のために作成頻繁にいくつかのシステムでは、ノード削除接合するたびにポイントは、ヒープメモリの断片を大量に製造することが可能です。メモリの断片化と、直接の結果は、システムが遅い実行されていることです。これは、欠陥重リンクリストの実装です。

新しいリニアフォームの
デザインのアイデア:
ノードが動的の動的な作成と破棄に、この空間内のオブジェクトのすべての単一のリスト内に予約スペース高める
ためのフォーム単一のリスト+ =静的単一のリストを

継承階層静的単一のリスト

 

メモリ、単鎖及びその他の操作のさまざまな方法に、静的な単鎖付加は、実装前に全く同じです。

実施静的単一リンクリスト考え
を通してテンプレートを単一の静的メンバobjectlist(StaticLinkList)を定義し
、クラスに定義された固定サイズの空間(unsigned char型を[])
関数を作成し、破壊書き換え、方法メモリの割り当てと反発変化
ノードクラスに重みをアップロードオペレータは新しい、指定されたメモリ内のオブジェクトを作成します

静的単一リンクリストは、達成するために:

このタイプでのノードLinkList.hがどのように定義されるかを見てください。

構造体ノード:パブリックオブジェクト

{

  T value; //既然是泛指类型的value,那么这个value就有可能是一个对象(用户自定义类类型的对象),必然牵涉到构造函数调用的问题了。value构造函数的调用,必然牵涉到Node构造函数的调用了(value是Node的一个成员变量)

  Node* next;

};

在StaticLinkList.h中,再看一下create函数的定义,

Node* create()

    {

        Node* ret = NULL;

        for(int i=0; i<N; i++)  //首先遍历空间哪些是可用的,就是通过这个标记数组来判断。

        {

            if(!m_used[i])

            {

                ret = reinterpret_cast<SNode*>(m_space) + i; //首先做强制类型转换,再做指针运算。内存分配好了之后,还需要在指定的内存上调用构造函数,因此需要重载new操作符。

                m_used[i] = 1;

                break;

            }

        }

        return ret;

    }

这里面不涉及Node构造函数的定义。仅仅是单纯的分配内存,并没有涉及到构造函数的调用。

分配好内存之后,我们还需要在指定的内存上调用构造函数。此时就需要重载new操作符了。

struct SNode : public Node

{

  //loc保存了一个内存地址,该内存地址就是调用构造函数的内存地址

  void* operator new(unsigned int size, void* loc)

  {

    return loc;

  }

};

Node* create()

    {

        SNode* ret = NULL;

        for(int i=0; i<N; i++)  //首先遍历空间哪些是可用的,就是通过这个标记数组来判断。

        {

            if(!m_used[i])

            {

                ret = reinterpret_cast<SNode*>(m_space) + i; //首先做强制类型转换,再做指针运算。内存分配好了之后,还需要在指定的内存上调用构造函数,因此需要重载new操作符。

                ret = new(ret) SNode();

                m_used[i] = 1;

                break;

            }

        }

        return ret;

    }

void destroy(Node* pn)

{

  SNode* space = reinterpret_cast<SNode*>(m_space);

  SNode* psn = dynamic_cast<SNode*>(pn);//从父类指针,转换为子类指针,直接调用dynameic_cast

 

  for(int i=0; i<N; i++)

  {

    if(psn == (space + i))

    {

      m_used[i] = 0;

      psn->~SNode();

    }

  }

}

具体代码如下:

#ifndef STATICLINKLIST_H
#define STATICLINKLIST_H

#include "linklist.h"

namespace DTLib
{

template <typename T,int N> //N用来定义预留大小空间使用的
class StaticLinkList : public LinkList<T>
{
protected:
    typedef typename LinkList<T>::Node Node; //为什么需要加上typename,因为LinkList<T>::Node这种写法,根本就无法确定Node是一种类型还是静态成员变量。

    struct SNode : public Node
    {
        //loc保存了一个内存地址,该内存地址就是调用构造函数的内存地址
        void* operator new(unsigned int size, void* loc)
        {
            (void)size;
            return loc;
        }
    };

    unsigned char m_space[sizeof(SNode) * N]; //定义预留的空间
      int m_used[N]; //标记数组

    Node* create()
    {
        SNode* ret = NULL;

        for(int i=0; i<N; i++)  //首先遍历空间哪些是可用的,就是通过这个标记数组来判断。
        {
            if(!m_used[i])
            {
                ret = reinterpret_cast<SNode*>(m_space) + i; //首先做强制类型转换,再做指针运算。内存分配好了之后,还需要在指定的内存上调用构造函数,因此需要重载new操作符。
                       ret = new(ret) SNode();
                m_used[i] = 1;
                break;
            }
        }
        return ret;
    }

    void destroy(Node* pn)
    {
        SNode* space = reinterpret_cast<SNode*>(m_space);
        SNode* psn = dynamic_cast<SNode*>(pn);//从父类指针,转换为子类指针,直接调用dynameic_cast

          for(int i=0; i<N; i++)
        {
            if(psn == (space + i))
            {
                m_used[i] = 0;
                psn->~SNode();
            }
        }
    }

public:
    StaticLinkList()
    {
        for(int i=0; i<N; i++)
        {
            m_used[i] = 0;
        }
    }

    int capacity()
    {
        return N; //表示静态单链表最多可以容纳多少个数据元素
    }
};

}

#endif // STATICLINKLIST_H

LinkList中封装create和destroy函数的意义:

为静态单链表(StackLinkList)的实现做准备。StaticLinkList与LinkList的不同仅在于链表结点内存分配上的不同。因此将仅有的不同封装于父类和子类的虚函数中

小结:

顺序表与单链表相结合后衍生出静态单链表

静态单链表是LinkList的子类,拥有单链表的所有操作

静态单链表在预留的空间中创建结点对象

静态单链表适合于频繁增删数据元素的场合(最大元素个数固定)

 

おすすめ

転載: www.cnblogs.com/-glb/p/12147366.html