【问题标题】:I need to do a deep copy, am I using my copy constructor correctly?我需要做一个深拷贝,我是否正确使用了我的复制构造函数?
【发布时间】:2019-10-17 21:20:05
【问题描述】:

我需要做一个深拷贝。我是否正确使用了我的复制构造函数?我应该改变什么?

#include <iostream>
#include <sstream>
using namespace std;

class LinkedList
{
    public:
        int data;
        LinkedList* prevNode;

        LinkedList()
        {
            int dd = 0;
            prevNode = nullptr;
        }

        LinkedList(int dd, LinkedList* pr)
        {
            data = dd;
            prevNode = pr;
        }
};

class Stack
{
    private:
        LinkedList* topNode;

    public:
        Stack();
        Stack(const Stack& original);
        ~Stack();

        bool isEmpty() const;
        int top() const;
        int pop();
        void push(int);
};

Stack::Stack()
{
    topNode = nullptr;
}

Stack::Stack(const Stack& original)
{
    this->topNode = original.topNode;
}

Stack::~Stack()
{
    while (!isEmpty())
    {
        pop();
    }
}

bool Stack::isEmpty() const
{
    if (topNode == NULL)
    {
        return true;
    }
    return false;
}

int Stack::top() const
{
    if (isEmpty())
    {
        throw runtime_error("error: stack is empty");
    }
    return topNode->data;
}

int Stack::pop()
{
    int topVal = top();

    LinkedList* oldtop = topNode;
    topNode = topNode->prevNode;
    return topVal;
}

void Stack::push(int newData)
{
    LinkedList* newNode = new LinkedList(newData, topNode);
    topNode = newNode;
}

int returnNumber(string inputString)
{
    istringstream fr(inputString); 
    int number;

    while (fr >> number)
    { 
        return number;
    }
    if (fr.fail())
    {
        throw runtime_error("error: not a number");
    }

    return number;
}

void list(Stack s)
{
    cout << "[";
    while (!s.isEmpty())
    {
        cout << s.pop();
        if (!s.isEmpty())
        {
            cout << ",";
        }
    }
    cout << "]" << endl;
}

void readCommands(Stack& newStack)
{
    string command = " ";
    while (command != "end")
    {
        cout << "stack> ";
        cin >> command;
        cout << endl;
        if (cin.eof())
        {
            break;
        }

        try 
        {
            if (command == "top")
            {
                cout << newStack.top() << endl;
            }
            else if (command == "pop")
            {
                cout << newStack.pop() << endl;
            }
            else if (command == "push")
            {
                string inputValue;
                cin >> inputValue;

                int number = returnNumber(inputValue);
                newStack.push(number);
                cin.ignore();
            }
            else if (command == "list")
            {
                list(newStack);
            }
            else
            {  
                if (command != "end")
                {
                    throw runtime_error("error: invalid command");
                }
            }
        }
        catch (runtime_error e)
        {
            cout << e.what() << endl;
        } 
    }
}

int main()
{
    Stack newStack;

    readCommands(newStack);
    return 0;
}

【问题讨论】:

  • 看起来是在做浅拷贝。你应该做一个深拷贝。
  • 这与编译器生成的默认复制构造函数完全相同。
  • 当你完成这项工作时,将其用于代码审查codereview.stackexchange.com(不过需要先工作)。
  • 对于new 的每次调用必须对应到delete 的调用。我没有看到任何删除调用(也许当您弹出一个项目并且不保留参考时?)。
  • 请不要这样删除你的问题!这使得奇普斯特的回答一文不值。我已将其回滚到以前的编辑。您可以不说谢谢,而是对答案投赞成票并接受(通过单击答案左侧的大勾号)。

标签: c++ linked-list stack copy-constructor


【解决方案1】:

我需要做一个深拷贝,我是否正确使用了我的复制构造函数?

没有。要进行深拷贝,您需要在新堆栈中分配新空间。看起来像这样:

class LinkedList
    {
        public:
             static LinkedList* Copy(LinkedList* c) {
                  if(c == nullptr) {
                       return nullptr;
                  } else {
                      return new LinkedList(data, Copy(prevNode));
                  }
             }
};

此静态函数接受任何指针并创建其值及其列表的副本。

然后,在你的堆栈中:

Stack::Stack(const Stack& original)
    {
        this->topNode = LinkedList::Copy(original.topNode);
    }

通过这种方式,您实际上是在创建新内存,而不是盲目地复制指针。这就是深拷贝的伟大理念。

如果您仍然对深度副本的工作原理感到困惑,我建议您咨询您的教科书或教授。

【讨论】:

    猜你喜欢
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多