如何在 C++ 中克隆对象?或者有其他解决方案吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12902751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to clone object in C++ ? Or Is there another solution?
提问by mert
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?
我写了一个堆栈和队列实现(基于链表)。有一个堆栈 ( bigStack
)。例如,我分开bigStack
(例如:stackA
和stackB
)。我pop()
是一个节点bigStack
,我push()
在stackA
。同样,我push()
在stackB
. 我不想bigStack
改变。因此我想克隆该bigStack
对象。如何在 C++ 中克隆对象?或者我的问题还有其他解决方案吗?
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();
回答by John Dibling
The typical solution to this is to write your own function to clone an object. If you are able to provide copy constructors and copy assignement operators, this may be as far as you need to go.
对此的典型解决方案是编写自己的函数来克隆对象。如果您能够提供复制构造函数和复制赋值运算符,这可能是您需要的。
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
Sometimes it is beneficial to provide an explicit clone()
method, especially for polymorphic classes.
有时提供显式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();
EDIT: Since Stack
has no member variables, there's nothing to do in the copy constructor or copy assignment operator to initialize Stack
's members from the so-called "right hand side" (rhs
). However, you still need to ensure that any base classes are given the opportunity to initialize theirmembers.
编辑:由于Stack
没有成员变量,因此在复制构造函数或复制赋值运算符中无需执行任何操作即可Stack
从所谓的“右侧”( rhs
)初始化的成员。但是,您仍然需要确保任何基类都有机会初始化它们的成员。
You do this by calling the base class:
你可以通过调用基类来做到这一点:
Stack(const Stack& rhs)
: List(rhs) // calls copy ctor of List class
{
}
Stack& operator=(const Stack& rhs)
{
List::operator=(rhs);
return * this;
};
回答by Kirill Kobelev
In C++ copying the object means cloning. There is no any special cloning in the language.
在 C++ 中,复制对象意味着克隆。该语言没有任何特殊的克隆。
As the standard suggests, after copying you should have 2 identical copies of the same object.
正如标准所建议的那样,复制后您应该拥有同一对象的 2 个相同副本。
There are 2 types of copying: copy constructor when you create object on a non initialized space and copy operator where you need to release the old state of the object (that is expected to be valid) before setting the new state.
有两种类型的复制:在未初始化的空间上创建对象时的复制构造函数和需要在设置新状态之前释放对象的旧状态(预期有效)的复制运算符。
回答by WeirdlyCheezy
If your object is not polymorphic (and a stack implementation likely isn't), then as per other answers here, what you want is the copy constructor. Please note that there are differences between copy construction and assignment in C++; if you want both behaviors (and the default versions don't fit your needs), you'll have to implement both functions.
如果您的对象不是多态的(并且堆栈实现可能不是),那么根据此处的其他答案,您想要的是复制构造函数。请注意,C++ 中的复制构造和赋值之间存在差异;如果您想要这两种行为(并且默认版本不符合您的需要),则必须实现这两个功能。
If your object is polymorphic, then slicing can be an issue and you might need to jump through some extra hoops to do proper copying. Sometimes people use as virtual method called clone() as a helper for polymorphic copying.
如果您的对象是多态的,那么切片可能是一个问题,您可能需要跳过一些额外的圈子来进行正确的复制。有时人们使用称为 clone() 的虚拟方法作为多态复制的助手。
Finally, note that getting copying and assignment right, if you need to replace the default versions, is actually quite difficult. It is usually better to set up your objects (via RAII) in such a way that the default versions of copy/assign do what you want them to do. I highly recommend you look at Meyer's Effective C++, especially at items 10,11,12.
最后,请注意,如果您需要替换默认版本,正确复制和分配实际上是非常困难的。通常最好以这样的方式设置对象(通过 RAII),使默认版本的复制/分配执行您希望它们执行的操作。我强烈建议您查看Meyer 的 Effective C++,尤其是第 10、11、12 项。