在C ++中实现int堆栈

时间:2013-10-30 18:35:53

标签: c++ oop stack operator-overloading

我在网上看到了一个练习,这是文字:

  

编写一个类int_stack来管理一堆整数。该   整数值将存储在动态分配的数组中。

     

本课程将提出以下成员函数:

     

将动态分配n的int_stack(int n)构造函数   整数,

     

int_stack()构造函数分配20个整数,

     

~int_stack()析构函数,

     

int empty()如果​​堆栈为空,返回值为1,为0   否则,

     

int full()如果堆栈已满,则返回值为1,否则返回0,

     

void operator< (int p)在堆栈上推送(添加)p值,

     

int operator>(int p)返回(并删除)顶部的值   堆栈

我试图实现它,但> (拉)操作员将无法工作。

这是我的代码:

int_stack.h

class int_stack
{
private:
    int* stack;
    unsigned int n, p;
    void init(unsigned int n);

public:
    int_stack(unsigned int n);
    int_stack();
    ~int_stack();
    int empty();
    int full();
    void operator <(int i);
    int operator >(int i);
};

int_stack.cpp

#include "int_stack.h"

void int_stack::init(unsigned int n)
{
    this->stack = new int[n];
    this->p = 0;
}

int_stack::int_stack(unsigned int n)
{
    this->init(n);
}

int_stack::int_stack()
{
    this->init(20);
}

int_stack::~int_stack()
{
    delete this->stack;
}


int int_stack::empty()
{
    return (this->p == 0 ? 1 : 0);
}

int int_stack::full()
{
    return (this->p == n-1 ? 1 : 0);
}

void int_stack::operator <(int i)
{
    if (!this->full())
        this->stack[p++] = i;
}

int int_stack::operator >(int i)
{
    if(!this->empty())
        return this->stack[p--];
    return 0;
}

我做错了什么?

4 个答案:

答案 0 :(得分:1)

除了使索引正确之外,该类还需要一个复制构造函数和赋值运算符。如上所述,您将获得同一数据块的多个删除:

int_stack s0;
int_stack s1(s0); // uh-oh

两个析构函数都将删除由s0

的构造函数分配的数组

答案 1 :(得分:1)

您的代码有几个主要缺陷:

除非你想分别在每次推送或弹出一些东西时调整堆栈大小,否则你可能想要使用链表或双端存储结构而不是矢量/数组样式。

重载operator<operator>以执行相当于提取和插入的操作是一个糟糕的界面选择。我会敦促不要在这些操作中使用运算符:

void int_stack::push(int i)
{
    // push an element onto the stack
}

int int_stack::pop()
{
    // pop an element off of the stack
}

因为您没有将其实现为链接列表或双端队列,所以当您转到推送元素时,您可以(并最终将)尝试在您分配的内存范围之外进行写入。

最后,您不能正确删除堆栈。如果您使用new [],则还必须使用delete []

答案 2 :(得分:0)

界面的选择非常糟糕,但忽略这一事实会考虑你的成员的意思,特别是p。索引p指的是上面最后添加的元素的位置。当您在pop操作中返回值时,您正在从该位置读取值,但该位置没有值:

int int_stack::operator >(int i)
{
    if(!this->empty())
        return this->stack[p--];   // <-- predecrement!
    return 0;
}

关于界面,operator<operator>是推送和弹出操作的不自然选择。当有人读入代码s < 5时,他们会解释您正在将s与5进行比较,而不是将元素插入堆栈s。这将成为混乱的根源。

operator< operator>定义为int operator>(int)更糟糕。用于读取值的用户代码最终将显示为:

value = s > 5;

看起来比较s到5,并将结果存储到value。此外,实际行为完全独立于参数5,相同的操作可以拼写为s > -1甚至s > 5.3

答案 3 :(得分:-1)

这是我提出的工作实现。

它实现了一个复制构造函数和赋值运算符。

此外,索引工作正常,界面已从<>运算符更改为两个简单的push(int)int pop()函数。

当您尝试按下/弹出边界时,它会抛出异常。

int_stack.h

#include <exception>

class int_stack
{
private:
    int* stack;
    unsigned int n, p;
    void init(unsigned int n);
    void copy(int_stack& other);

public:
    int_stack(unsigned int n);
    int_stack();
    int_stack(int_stack& other);
    int_stack& operator=(int_stack& other);
    ~int_stack();
    int empty();
    int full();
    void push(int i);
    int pop();
    class OutOfBoundariesException: public std::exception {};
};

int_stack.cpp

#include "int_stack.h"

void int_stack::init(unsigned int _n)
{
    n = _n;
    stack = new int[n];
    p = 0;
}

int_stack::int_stack(unsigned int n)
{
    init(n);
}

int_stack::int_stack()
{
    init(20);
}

int_stack::int_stack(int_stack& other)
{
    copy(other);
}

int_stack& int_stack::operator=(int_stack& other)
{
    copy(other);
    return *this;
}

void int_stack::copy(int_stack& other)
{
    n = other.n;
    p = other.p;
    stack = new int[n];
    for (unsigned int i = 0; i < n; i++)
        stack[i] = other.stack[i];
}

int_stack::~int_stack()
{
    delete[] stack;
}

int int_stack::empty()
{
    return (p == 0 ? 1 : 0);
}

int int_stack::full()
{
    return (p == n ? 1 : 0);
}

void int_stack::push(int i)
{
    if (!full())
        stack[(++p)-1] = i;
    else
        throw new OutOfBoundariesException;
}

int int_stack::pop()
{
    if (!empty())
        return stack[(p--)-1];
    else
        throw new OutOfBoundariesException;

    return 0;
}