【问题标题】:C++ own Stack of objects. What is copied at push()?C++ 自己的堆栈对象。 push() 中复制了什么?
【发布时间】:2020-05-16 20:22:27
【问题描述】:

好吧,我在一个 Class 中实现了一个 FIFO 堆栈(push,pop)堆栈,其中分配了 mem 整数。 所以我问自己:如果“int”是一种数据类型,为什么我不能将“ADTs”推送到我自己的堆栈中。

然后我得到了这个代码:

#include <iostream>

class Person {
    std::string name;
    int age;
public:
    Person(std::string pName = "", int pAge = 1)
    {
        name = pName;
        age = pAge;
    }
    void Print()
    {
        std::cout << name << " " << age << std::endl;
    }

};

class Stack {
    Person * stack;
    int size, top;
    int index;
public:
    Stack(int stackSize)
    {
        top = stackSize -1;
        index = top;
        stack = new Person[stackSize];
    }
    void push(Person person)
    {
        if (index < 0)
            std::cout << "Stack UNDERFLOW" << "Index is: " << index << std::endl;
        stack[index--] = person;
    }
    Person & pop()
    {
        if (index > top)
        {
            std::cout << "Stack OVERFLOW" << std::endl;
        }   
        return stack[++index];
    }
};

我知道,STL 库中有堆栈、队列、vectos 等。我只是想自己做。 我想要堆栈推送对象的副本。 我不确定我不知道编译器是在推送地址、复制整个对象(我想要什么)还是什么。

请启发我。

这是我的 main() 代码:

int main()
{
    Stack stack(100);
    Person person("Lucas", 39);
    for (int i = 0; i < 100; i++)
    {   
        stack.push(person);
        ((Person)stack.pop()).Print();
    }

    return EXIT_SUCCESS;
}

【问题讨论】:

  • 然后我得到了这个代码: -- 你可以参加你的工作 int 类,用 T 替换所有这些 int,然后创建一个模板基于T,而不是复制粘贴,希望你没有犯错。这将是检验您的代码是否可以使用多种类型的终极测试。
  • @PaulMcKenzie:没错,真是个傻瓜。去试试……
  • ((Person)stack.pop()).Print(); -- 在此处解释您要执行的操作。额外的演员阵容是完全没有必要的。
  • @PaulMcKenzie 你是对的。现在我明白了。我创建了一个模板并忘记了那个不必要的“演员”。它就像一个魅力!非常感谢您,抱歉的问题。

标签: c++ stack


【解决方案1】:

要回答您关于副本的问题,如下:

stack[index--] = person;

复制一份,因为赋值两边的类型都是T

这个:

stack.push(person);

也会复制,因为您通过值传递person。为避免此(冗余)副本,请将push 声明为:

void push(const T &person)

【讨论】:

  • 我查看了我的代码。我认为这就是 push() 的方式。我将删除我的答案,因为我还有一个问题。
【解决方案2】:

好吧,我为解决我的问题所做的是@PaulMcKenzie 在his comment 中所说的话。 我为“Stack”类创建了一个模板,任何模板“T”都是传递给此类的数据类型。 关于主要方法(在​​我的问题中),它对 (Person) 进行了不必要的强制转换,因为它是隐含的。 编辑2: @Paul Sanders 也是对的,我在 push() 处做了一个冗余副本

这样我解决了我的问题:

#include <iostream>

class Person {
    std::string name;
    int age;
public:
    Person(std::string pName = "", int pAge = 1)
    {
        name = pName;
        age = pAge;
    }
    void Print()
    {
        std::cout << name << " " << age << std::endl;
    }

};

template <class T>
class Stack {
    T * stack;
    int size, top;
    int index;
public:
    Stack(int stackSize)
    {
        top = stackSize -1;
        index = top;
        stack = new T[stackSize];
    }
    void push(const T &person)
    {
        if (index < 0)
            std::cout << "Stack UNDERFLOW" << std::endl;
        stack[index--] = person;
    }
    T pop()
    {
        if (index > top)
        {
            std::cout << "Stack OVERFLOW" << std::endl;
        }   
        return stack[++index];
    }
};

int main()
{
    Stack<Person> stack(100);
    Person person1("Lucas", 39);
    Person person2("Gustavo", 38);
    for (int i = 0; i < 100; i++)
    {
        if (i % 2 == 0)
            stack.push(person1);
        else
            stack.push(person2);
    }   
    for (int i = 0; i < 100; i++)
        stack.pop().Print();
    return EXIT_SUCCESS;
}

在 main() 函数的示例中,它创建了 100 个 Person 对象的堆栈。然后我创建了 2 个人:“Lucas”和“Gustavo”,并将其插入到我的堆栈中 100 次(第一次声明)。 然后是第二个也是最后一个 for 语句 pop() 所有值并打印出来。

【讨论】:

    猜你喜欢
    • 2014-02-28
    • 2014-11-29
    • 2012-02-05
    • 2010-09-30
    • 2016-02-04
    • 1970-01-01
    • 2011-05-07
    • 2020-08-22
    • 2016-07-28
    相关资源
    最近更新 更多