30

I wrote a Stack and Queue implementation (Linked List based). There is one stack (bigStack). For example, I separate bigStack (example: stackA and stackB). I pop() a node from bigStack, I push() in stackA. In the same way, I push() in stackB. I want bigStack to not change. Therefore I want to clone the bigStack object. How do I clone objects in C++? Or is there another solution to my problem?

class Stack : public List {
public:
   Stack() {}
   Stack(const Stack& rhs) {}
   Stack& operator=(const Stack& rhs) {};
    ~Stack() {}

    int Top() {
        if (head == NULL) {
            cout << "Error: The stack is empty." << endl;
            return -1;
        } else {
            return head->nosu;
        }
    }

    void Push(int nosu, string adi, string soyadi, string bolumu) {
        InsertNode(0, nosu, adi, soyadi, bolumu);
    }

    int Pop() {
        if (head == NULL) {
            cout << "Error: The stack is empty." << endl;
            return -1;
        } else {
            int val = head->nosu;
            DeleteNode(val);
            return val;
        }
    }

    void DisplayStack(void);

};

then...

Stack copyStack = veriYapilariDersi;
copyStack.DisplayStack();
4

3 回答 3

39

典型的解决方案是编写自己的函数来克隆对象。如果您能够提供复制构造函数和复制赋值运算符,这可能是您需要的。

class Foo
{ 
public:
  Foo();
  Foo(const Foo& rhs) { /* copy construction from rhs*/ }
  Foo& operator=(const Foo& rhs) {};
};

// ...

Foo orig;
Foo copy = orig;  // clones orig if implemented correctly

有时提供显式clone()方法是有益的,尤其是对于多态类。

class Interface
{
public:
  virtual Interface* clone() const = 0;
};

class Foo : public Interface
{
public:
  Interface* clone() const { return new Foo(*this); }
};

class Bar : public Interface
{
public:
  Interface* clone() const { return new Bar(*this); }
};


Interface* my_foo = /* somehow construct either a Foo or a Bar */;
Interface* copy = my_foo->clone();

编辑:由于Stack没有成员变量,因此在复制构造函数或复制赋值运算符中无需Stack从所谓的“右手边”(rhs)初始化 的成员。但是,您仍然需要确保任何基类都有机会初始化成员。

您可以通过调用基类来做到这一点:

Stack(const Stack& rhs) 
: List(rhs)  // calls copy ctor of List class
{
}

Stack& operator=(const Stack& rhs) 
{
  List::operator=(rhs);
  return * this;
};
于 2012-10-15T19:42:34.723 回答
2

如果您的对象不是多态的(并且堆栈实现可能不是),那么根据此处的其他答案,您想要的是复制构造函数。请注意,C++ 中的复制构造和赋值是有区别的;如果你想要这两种行为(并且默认版本不符合你的需要),你必须实现这两个功能。

如果您的对象是多态的,那么切片可能是一个问题,您可能需要跳过一些额外的环节才能进行正确的复制。有时人们使用名为 clone() 的虚拟方法作为多态复制的助手。

最后,请注意,如果您需要替换默认版本,则正确进行复制和分配实际上是相当困难的。通常最好设置您的对象(通过 RAII),以便默认版本的复制/分配执行您希望它们执行的操作。我强烈建议您查看Meyer 的 Effective C++,尤其是第 10、11、12 项。

于 2012-10-15T20:15:58.110 回答
2

在 C++ 中,复制对象意味着克隆。该语言没有任何特殊的克隆。

正如标准所建议的那样,在复制后,您应该拥有同一对象的 2 个相同副本。

有两种类型的复制:在非初始化空间上创建对象时的复制构造函数和在设置新状态之前需要释放对象的旧状态(预期有效)的复制运算符。

于 2012-10-15T19:42:50.207 回答