2013-10-30 88 views
-1

我碰到一个锻炼来在网络上,这是文字:实现C++中的INT堆栈

编写类int_stack将管理整数堆栈。整数值将被存储在动态分配的数组中。

这个类将提出以下的成员函数:

int_stack(INT n)的构造,将动态分配Ñ 整数,

int_stack()构造分配20点的整数,

〜int_stack( )析构函数,

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

INT满()的返回值是1,如果堆栈已满,否则为0,

void运算<(INT p)的推压(添加)在堆栈上的p值,

INT操作> (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; 
} 

我在做什么错?

+0

在什么意义上它不工作?编译器错误?运行时错误?或者是什么? – 2013-10-30 18:38:07

+1

'p'是项目的数量,但是你的数组索引是'0-(p-1)'。 – Joe

+1

这是一个相当差的设计,所以不要付出太多的努力来实现它。使用'>'和'<'进行push和pop是非常可怕的,并且使用'empty()'和'full()'return'int'(C++具有'bool')意味着设计它的人真的不知道什么他们在做。 –

回答

0

界面的选择很不好,但是忽略这个事实考虑你的成员的意思,特别是p。索引p是指以上位置最后添加的元素。当您在pop操作你正在阅读从该位置值返回值,但该位置没有值:

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

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

operator<更差的是operator>定义为int operator>(int)。用户代码读取值会显得如:

value = s > 5; 

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

1

除了获得索引权,类需要一个拷贝构造函数和赋值运算符。至于写你会得到相同的数据块的多个删除:

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

两个析构函数将删除由构造为s0分配的阵列。

+0

我该如何执行它们?在复制p和n之后,我应该复制堆栈,但是如何在不公开的情况下做到这一点? –

+1

@RiccardoBestetti - 复制构造函数是一个成员,因此它可以访问它正在复制的对象的私有数据。尝试一下。 –

1

有你的代码的几大缺陷:

除非你希望每次按压时间或流行的东西来调整堆栈上或关闭它分别,你可能想使用一个链接列表 - 或deque-style存储结构而不是vector/array-style。

超载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 []

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