如何使我的堆栈类动态

how to make my stack class dynamic

本文关键字:动态 堆栈 我的 何使      更新时间:2023-10-16

我用c++写了一个堆栈类(如下所示),但它是静态的,并且肯定会使用大量内存。如何使其动态,以便在需要时为对象添加内存,在弹出内容时自动删除内存?

template <class T>
class stack
{
private:
    T value[512];
    uint16_t length;
public:
    stack()
    {
        length=0;
    }
    stack(T _input)
    {
        value[0]=_input;
        length=1;
    }
    bool push(T _input)
    {
        if(length+1<512)
        {
            value[++length]=_input;
            return true;    
        }
        else
            return false;
    }
    T pop()
    {
        return value[length--];     
    }
    T peak()
    {
        return value[length];   
    }
    bool has_data()
    {
        return (length>0?true:false);
    }
};

您必须在需要时动态地分配它。比如:

#define STACK_INITIAL_ALLOC   32
#define STACK_CHUNK_ALLOC    32
template<typename T>
class Stack
{
public:
    Stack()
        : data(0), entries(0), allocated(0)
        { }
    Stack(const T &value)
        : data(0), entries(0), allocated(0)
        {
            push(input);
        }
    ~Stack()
        {
            if (data)
                delete [] data;
        }
    void push(const T &value)
        {
            if (entries == allocated)
                allocate();  // Allocate more memory
            data[entries++] = value;
        }
    T pop()
        {
            if (entries > 0)
            {
                shrink();
                return data[--entries];
            }
            else
                throw runtime_error("stack empty");
        }
    T &top()
        {
            if (entries > 0)
                return data[entries - 1];
            else
                throw runtime_error("stack empty");
        }
    // Return the number of entries in the stack
    size_t count() const
        {
            return entries;
        }
private:
    T      *data;      // The actual stack
    size_t  entries;   // Number of entries in stack
    size_t  allocated; // Allocated entries in stack
    void copy(T *from, T *to)
        {
            for (size_t i = 0; i < entries; i++)
                *to++ = *from++
        }
    void allocate()
        {
            if (data == 0)
            {
                allocated = STACK_INITIAL_ALLOC;
                data = new T[allocated];
            }
            else
            {
                // We need to allocate more memory
                size_t new_allocated = allocated + STACK_CHUNK_ALLOC;
                T *new_data = new T[new_allocated];
                // Copy from old stack to new stack
                copy(data, new_data);
                // Delete the old data
                delete [] data;
                allocated = new_allocated;
                data = new_data;
            }
        }
    // Shrink the stack, if lots of it is unused
    void shrink()
        {
            // The limit which the number of entries must be lower than
            size_t shrink_limit = allocated - STACK_CHUNK_ALLOC * 2;
            // Do not shrink if we will get lower than the initial allocation (shrink_limit > STACK_INITIAL_ALLOC)
            if (shrink_limit > STACK_INITIAL_ALLOC && entries < shrink_limit)
            {
                // We can shrink the allocated memory a little
                size_t new_allocated = allocated - STACK_CHUNK_ALLOC;
                T *new_data = new T[new_size];
                copy(data, new_data);
                delete [] data;
                data = new_data;
                allocated = new_allocated;
            }
        }
};

也是一个小小的免责声明,这段代码是直接写入浏览器的。它没有经过测试,但原则上应该有效……:)

您也可以使用std::vector:

template <class T>
class stack{
private:
std::vector<T> vec;
public:
inline void push(T arg){vec.push_back(arg);};
inline T pop(){return vec.pop_back();};
};

任何数组结构的增长和收缩都是昂贵的(T必须是可复制构造的),并且必须移动所有现有的T。如果你发现你在做大量的推/弹出操作,并且你需要保持较低的内存使用量,尝试在内部使用链表。它只需要被单独链接。

这是一个草图:

template <class T>
class stack
{
  struct Node
  {
    T data;
    Node* next;
  };
public:
  // methods
private:
  Node *head;
};

现在,要在堆栈上推送一些东西,用T构造一个Node,将它的下一个指针设置为当前的head,将head设置为Node指针。弹出包括将nexthead中取出并将其设置为head

当然,你需要正确地管理内存的销毁等

编辑:啊,看来我假设你可能知道c++的基础知识是不正确的,我假设你做了,因为你正在使用模板。在这种情况下,忽略这个答案,直到你掌握了基本知识!