【问题标题】:Use of pointers in a stack class?在堆栈类中使用指针?
【发布时间】:2014-06-21 01:35:59
【问题描述】:

我正在学习 C++,我们得到了一个使用类模板和指针制作堆栈类的练习。我还没有完全理解堆栈或指针的实现,所以我试了一下并制作了这个类:

template <class T>
class Stack_Class {
public:
    T* stack;
    int item_quantity;
    T* First_item;
    int Max_quantity;

    Stack_Class(int value);
    ~Stack_Class();
    bool Add(T value);
    T Pop();
    int GetMax_Quantity();
    bool Full();
    bool Empty();
};


template <class T>
Stack_Class<T>::Stack_Class(int value) {
    if (value > 0) {
        stack = new T[value];
        First_item = stack;
        item_quantity = 0;
        Max_quantity = value;
    }
}

template <class T>
Stack_Class<T>::~Stack_Class() {
    if (First_item) {
        delete First_item;
    }
}



template<class T>
bool Stack_Class<T>::Add(T num) {
    if (item_quantity <Max_quantity) {

        *stack = num;
        stack++;
        item_quantity++;
        return true;
    }
    else return false;
}

template<class T>
T Stack_Class<T>::Pop() {
    if (!Empty()) {
        item_quantity--;
        return stack[item_quantity];
    }
     return NULL;
}

template<class T>
bool Stack_Class<T>::Empty() {
    return (item_quantity == 0);
}

template <class T>
int Stack_Class<T>::GetMax_Quantity() {
    return Max_quantity;
}

主要课程是:

#include <iostream>
#include "Stack_Class.h"

void main() {
    Stack_Class<int> intStack(3);

    intStack.Add(1);
    intStack.Add(2);
    intStack.Add(3);
    int count = intStack.GetMax_Quantity();

    for (int i = 0; i < count; i++) {
        std::cout << "Pop No: " << i << " - Elemento: "  << intStack.Pop() << std::endl;
    }
}

虽然结果是我得到了所有随机数,而不是我在 intStack 中给出的随机数。添加,所以我的问题是我在这里正确地实现了指针?

【问题讨论】:

  • stack = new T[value]; -> 你的意思是那个还是构造函数?因为你不使用 delete[] 那么等等。
  • @keyser:说出确切的疑问会更有用。
  • @LaszloPapp 是的,不过在这种情况下我会完全撤回它们:)
  • 您在索引 (stack[item_quantity]) 和移动指针 (stack++) 之间混合使用,这可能是您困惑的根源。

标签: c++ pointers stack


【解决方案1】:

您正在混淆Add 方法中的指针递增语义和Pop 方法中的索引语义。

由于您需要 Empty 方法的索引等,我将修复您的 Add 方法而不是 Pop,如下所示。

否则,您最终仍会在某些方法中使用索引,而在其他方法中则不会。对我来说这看起来不一致。

template<class T>
bool Stack_Class<T>::Add(T num){
    if (item_quantity <Max_quantity){       

        stack[item_quantity++] = num;
        return true;
    }
    else return false;
}

您的代码中的另一个问题是:

stack = new T[value];

但您似乎只删除了指针中的第一个元素。这是有保证的(并且可能不可忽略的)内存泄漏。

即使你修复了所有这些,你的代码仍然无法编译,因为你试图返回 void,而 C++ 程序应该返回 int,所以改变这个:

void main(){
    ...
}

到:

int main(){
    ...
}

...并相应返回一个像0这样的整数。

您还需要修复此警告:

Stack_Class.h:56:13:警告:从 NULL [-Wconversion-null] 转换为非指针类型“int” 返回空值; ^

例如,将 NULL 更改为 0。

修复所有这些后,输出如下:

Pop No: 0 - Elemento: 3
Pop No: 1 - Elemento: 2
Pop No: 2 - Elemento: 1

还可以看到运行on ideone的代码。

为方便起见,这是修复后的完整工作代码:

template <class T>
class Stack_Class{
public:
    T* stack;
    int item_quantity;
    T* First_item;
    int Max_quantity;

    Stack_Class(int value); 
    ~Stack_Class();
    bool Add(T value);
    T Pop();
    int GetMax_Quantity();
    bool Full();
    bool Empty();   
};


template <class T>
Stack_Class<T>::Stack_Class(int value){
    if (value > 0){
        stack = new T[value];
        First_item = stack;
        item_quantity = 0;
        Max_quantity = value;
    }
}

template <class T>
Stack_Class<T>::~Stack_Class(){
    if (First_item){
        delete First_item;
    }
}



template<class T>
bool Stack_Class<T>::Add(T num){
    if (item_quantity <Max_quantity){       

        *stack = num;
        stack++;
        item_quantity++;
        return true;
    }
    else return false;
}

template<class T>
T Stack_Class<T>::Pop(){
    if (!Empty()){
        item_quantity--;
        return stack[item_quantity];
    }
     return NULL;
}

template<class T>
bool Stack_Class<T>::Empty(){
    return (item_quantity == 0);
}

template <class T>
int Stack_Class<T>::GetMax_Quantity(){
    return Max_quantity;
}

【讨论】:

  • 是的,实际上我最初是这样创建 Add 方法的,但是我的老师告诉我,为了使用指针,我以其他方式实现。我会保存这个以供比较,谢谢!
  • @alpho:我不关注...堆栈已经是一个指针,索引它也是一个指针操作...
【解决方案2】:

Pop() 中引用stack 指针之前,您需要将其递减:

template<class T>
T Stack_Class<T>::Pop(){
    if (!Empty()){
        item_quantity--;
        stack--;
        return *stack;
    }
    return NULL;
}

您的数组访问 stack[item_quantity] 不起作用,因为您在 Add 中增加了 stack。所以构造后stack指向的内存是这样的

0xff65f96f  <-- *(stack + 0)
0x0eec604f  <-- *(stack + 1)
0x05be0582  <-- *(stack + 2)
0x29b9186e  <-- *(stack + 3)

十六进制值表示分配时内存中巧合的随机垃圾。这是因为new 分配的内存没有被初始化为好的东西。三个值相加后是这样的

1           <-- *(stack - 3)
2           <-- *(stack - 2)
3           <-- *(stack - 1)
0x29b9186e  <-- *(stack + 0)
0xf66eff06  <-- *(stack + 1)
0x357eb508  <-- *(stack + 2)

Pop 的第一次调用中,您访问了stack[2] = *(stack + 2),因为item_quantity 在自增后为2。对Pop 的两次连续调用访问stack[1]stack[0]。正如你在上面看到的,你从来没有真正引用你放入堆栈的值。

【讨论】:

  • 我更愿意修复 Add 方法,因为索引仍有待使用且索引为 O(1)。您可以重写空方法等以首先比较和堆栈,但是是的。更重要的是:即使在此之后代码也不会编译。
  • 这实际上修复了我得到的随机数,我没有意识到我没有使用 pop 方法的减量。非常感谢!
猜你喜欢
  • 2015-11-16
  • 1970-01-01
  • 2013-01-20
  • 2015-06-05
  • 1970-01-01
  • 2012-01-04
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多