如何在这段代码中实现“栈(stack)”的行为?C++

3

我想就这段代码提出两个问题,代码是模拟栈的实现。

Stack.h

 #pragma once

namespace stackandqueue {

    class Stack
    {
    private:
        int index;
        int *stackdata;

    public:     
        Stack();    
        ~Stack();
        void push(int val);
        int pop();
        int top();
        bool isEmpty();
    };

}

Stack.cpp

#include "stdafx.h"
#include "Stack.h"

namespace stackandqueue {

        Stack::Stack() : index{ 0 }
        {
            stackdata = new int[index];
        }
        Stack::~Stack()
        {
            delete[] &stackdata;
        }
        void Stack::push(int val) {
            stackdata[index] = val;
            index++;
        }
        int Stack::pop() {
            int val = stackdata[index];
            index--;
            return val;
        }
        int Stack::top() {
            return stackdata[index];
        }
        bool Stack::isEmpty() {
            return index == 0;
        }
}

意义在于让我创造。
 Stack stack;

然后它初始化一个动态数组,第一个索引为0,这让我可以推入、弹出和获取值。

第一个问题: 为什么我的方法定义存在未解析的符号?

第二个问题: 关于“stackdata”,如果我想声明一个具有动态大小的“数组”以实现此行为,您认为这是正确的方式吗?

我乐于接受改进和最佳实践。我习惯编程语言,但我从未深入学习过C++,我不想养成不良习惯。所以你看,我从头开始学起。

谢谢。


我发表了解决方案并得到了你的帮助,也许会对某些人有所帮助。

class Stack
    {
    private:
        int index;
        int* stackdata;

    public:     
        Stack(int size);    
        ~Stack();
        void push(int val);
        int pop();
        int top();
        bool isEmpty();
    };

    Stack::Stack(int size) 
        : index {0}, stackdata{new int[size]} 
        {
        }
        Stack::~Stack()
        {
            delete[] stackdata;
        }
        void Stack::push(int val) {
            stackdata[index] = val;
            index++;
        }
        int Stack::pop() {
            index--;
            return stackdata[index];
        }
        int Stack::top() {
            return stackdata[index-1];
        }
        bool Stack::isEmpty() {
            return index == 0;
        }
1个回答

5
这个有几个问题。
  1. 数组,无论是动态分配还是静态分配,都不是一个栈/队列/向量。你创建的实际上是0个整数。在此之后所有元素的访问都没有定义行为。你需要使你的数组能够增长,也就是说要变成一个向量,比如`std::vector`。

  2. `delete[] &stackdata` 的间接级别错误了。你想用的是`delete[] stackdata`。你试图删除的是没有动态分配的指针。

  3. 你缺少复制/移动构造函数和复制/移动赋值运算符,因此一旦你将`Stack`传输到任何地方,它就会崩溃。(原始实例将在已复制/移动的实例上执行`delete[]`!)阅读关于三五零法则的文章。

除此之外,看起来像是一个栈。

这里你没有未定义引用的问题,这很有趣,因为这是你唯一询问的问题。 :) 如果你确实遇到了这样的问题,那么可能是你的构建系统出了问题(编译该源文件失败),我们无法看到。


除此之外,我明白了。所以问题是我没有办法说“好的,我指向第一个地址和数据的大小(int),然后你从这里开始动态分配内存并在需要时重新分配”?我现在想避免使用std::vector。我必须定义一个已知大小的数组吗? - FooBarExtension
@FooBarExtension 是的。您需要创建一个类(与向量完全一样!),它重新分配更大的内存块,将旧内容复制到其中,然后释放旧的较小内存块。也可以根据需要缩小缓冲区的大小(尽管人们不太这样做;向量不会这样做)。new[]意味着您可以提供运行时边界,但这并不意味着无限/可变边界;您要求的内存就是您获得的内存。 - Lightness Races in Orbit
1
明白了。我听说过“不要重复造轮子”的说法。我会尝试使用std::vector。或者我会在构造函数中指定大小以使其具有动态性。我现在明白了。非常感谢你。 :) - FooBarExtension

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接