【问题标题】:How do I dynamically create a struct for a stack in C++?如何在 C++ 中为堆栈动态创建结构?
【发布时间】:2020-10-11 20:37:34
【问题描述】:

我正在为 C++ 程序开发堆栈程序。我已经完成了 isEmpty、peek 和 pop 的工作,但在上学期学习 Java 之后,我正试图找出 C++ 独有的一些东西。对于这个程序,我们正在创建一个指针堆栈,指向一个名为 Data 的 ADT 结构,它有两个属性(一个称为 id 的 int 和一个称为 data 的字符串)。

对于 push(),教授们要求我们“动态创建一个结构”来保存被推送的 Data 结构的值。我通常理解动态内存分配,因为它与 Java 中的 ArrayLists 有关,所以我知道他要求我们根据需要创建结构,但我正在努力将这些部分组合在一起。假设我在 push() 中有一个名为 pushData 的变量,它是一个 Data 结构。当我调用 push() 时,我使用传递给 push 的值分配 pushData 的属性,并将指向 pushData 的指针添加到堆栈中。

我最初的想法是创建一个并行数组作为 Stack 的一部分,它可以保存推入堆栈的每个 Data 结构的值,并且该结构数组可以与指针数组/堆栈平行。虽然我认为这可行,但必须有另一种方法,因为教授说我们不能修改 Stack 的属性,这意味着我不能创建一个并行数组来保存这些值。动态大小的数组是我记得过去教授讲动态分配内存概念的唯一方法,所以我不知道如何将它融入到这个特定的场景中。

如果这不是解决方案,那么我不知道在推送每个 Data 结构的值后保持它的最佳方法。我的假设是,当每次对 push 的调用完成时,pushData 结构将被删除,然后 push() 将重新创建 pushData 变量并在每次再次调用时为其赋予一个新值...

提前感谢您提供的任何帮助。我对自己感到很沮丧,因为我在这最后一种方法上感到非常困惑。提前感谢任何能够提供帮助的人。

我们得到了:

struct Data 
{ 
    int id; 
    string data; 
};

class Stack 
{ 
    public: 
    /* 
     * write all your public method prototypes here 
     */ 
    private: 
    /* write all your private method prototypes here */ 
    // these are the only attributes you need. do not modify them or add any 
    int top; // this is your top index 
    Data *stack[STACK_SIZE]; // this is your stack, it is an array of Data pointers 
};

【问题讨论】:

  • 听起来更像 C 但如果是 C++ 我会模仿 std::stack 的接口。您的结构是否有复制构造函数(或者是 PoD 类型)?如果您想手动使用 new/delete,那么您必须跟踪这些指针。
  • “最好的方法”是使用<stack>。让学生重新实现标准库(很糟糕),通过使用标准库将他们限制为 not 确实对每个人都不利。您永远不必自己实现基本数据结构,尤其是不是那些动态分配内存的结构。这就是标准库 的用途,以及您应该学习的内容...
  • @DevSolar,我确信在某些情况下知道如何实现 stack 很重要,而在某些情况下,只知道如何使用它很重要。
  • 教授给你的代码是什么样的?
  • @MarquisofLorne 正如我所说,将太多的 C++ 课程与普通的 Java 或 Python 课程进行比较。太多 1970 年的思维模式在那里继续,导致 C++ 仍然享有复杂的名声,而实际上情况恰恰相反。教他们每个结构是什么,在哪里可以找到它们,以及如何使用它们。我不同意实施它们的实践在那个级别上是有用的。此外,本土结构通常也不能很好地与<algorithm> 配合使用......

标签: c++ pointers stack dynamic-memory-allocation dereference


【解决方案1】:

我猜是为了学习,没问题。

对于堆栈,通常在创建堆栈时创建一个数组。通常这是唯一的动态内存分配。

复制数据时无需为其创建新内存。在 C++ 中,了解复制和移动语义以及 l-values 、 r-values 和 x-values 之间的区别很重要。

对于数据结构中的字符串,切记浅拷贝。

有了这个理解和一些指针算法,你应该能够完成你的任务

【讨论】:

    【解决方案2】:

    这是动态创建结构对象的方法

    struct Square
    {
        double side;
    };
    
    struct Rectangle
    {
        double length, width;
    };
    
    vector<void*> myBag; //This allows you to have a vector (ArrayList/List) of any type 
    vector<int> bagTracker; // 0: square, 1: rectangle we need a companion vector to track down the type of the objects pushed into the vector
    
    Square *square
    square = new Square;
    square->side = num1;
    
    myBag.push_back(square);
    bagTracker.push_back(0);
    
    Rectangle *rectangle
    rectangle = new Rectangle;
    rectangle->length = num1;
    rectangle->width = num2;
                    
    myBag.push_back(rectangle);
    bagTracker.push_back(1);
    

    为了访问您需要reinterpret_cast 将任何指针类型转换为任何其他数据类型的对象

    Square *square = reinterpret_cast<Square*>(myBag.at(i));
    cout << square->side << endl;
    

    同样适用于使用函数

    Square *square = reinterpret_cast<Square*>(myBag.at(i));
    outputSquare(cout, *square);
    

    希望这个答案或帮助

    编辑

    我忘了声明Square *squareRectangle *rectangle

    删除

    Square *square = reinterpret_cast<Square*>(myBag.at(i));
    delete square;
    

    【讨论】:

    • 你不deletenew。这将导致将来发生内存泄漏。
    • 此时我将开始谈论unique_ptr,但由于讲师显然不允许使用标准库,这也可能不是一个选项。 :-(
    • 我以前没有使用过向量,所以我需要熟悉它们才能更好地理解这个解决方案。此外,我们不允许修改结构的属性,所以无论如何我都无法将它们更改为向量。看到你使用 new 关键字,从去年秋季学期开始我第一次上 C++ 课时就想起了一些动态内存分配的记忆,但是当我尝试在我的程序中使用它时,我遇到了很多错误,我仍在努力理解.将在单独的评论中发布错误。
    • 我试过“pushData = new Data(idPushed, dataPushed);”并收到此错误消息:stack.cpp:在成员函数'bool Stack::push(int,std::string)'中:stack.cpp:74:4:错误:'pushData'未在此范围内声明74 | pushData = new Data(idPushed, dataPushed); | ^~~~~~~~ stack.cpp:74:44: error: no matching function for call to ‘Data::Data(int&, std::string&)’ 74 | pushData = new Data(idPushed, dataPushed); | ^ 在 stack.h:14 包含的文件中,来自 stack.cpp:10:
    • 续:data.h:21:8:注意:候选:'Data::Data()' 21 |结构数据 { | ^~~~ data.h:21:8: 注意:候选人需要 0 个参数,2 个提供的 data.h:21:8: 注意:候选人:'Data::Data(const Data&)' data.h:21:8 :注意:候选人需要 1 个参数,提供 2 个 data.h:21:8:注意:候选人:'Data::Data(Data&&)' data.h:21:8:注意:候选人需要 1 个参数,提供 2 个跨度>
    猜你喜欢
    • 1970-01-01
    • 2017-04-18
    • 2013-05-03
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-03
    相关资源
    最近更新 更多