2015-12-30 62 views
2

复制构造函数和赋值运算符都从一个对象复制到另一个对象,那么为什么我们需要这两个对象? Copyconstructor意味着它创建一个新对象并从另一个存在对象复制内容,并且赋值操作符将内容从一个现有对象复制到已经存在的对象。为什么我们需要在C++中完全使用复制构造函数和赋值运算符

所以最终两者都从一个对象将内容复制到另一个那么为什么我们既需要我们只能有一个正确的。

+1

如果语言设计为使用复制重构而不是赋值,则在重建之前可能需要销毁该对象。一个赋值操作符可以完成析构函数的作用,然后是构造函数的作用。或者,赋值运算符可能会跳过其中的一部分或以其他方式在较少的工作中获得相同的效果。 – JSF

+0

我认为简短的答案是,复制构造函数确实需要在那里或通过值不起作用,其他的东西不起作用。赋值运算符,你可能不需要强制性的,但在某些情况下,如果你能够重载它,速度可能会快很多,所以我们在这里......也不一定清楚赋值运算符应该是什么。有时候你想要它只是'memcpy',但是如果你的对象是一个聪明的指针,那么这会让你成为一只悲伤的熊猫。如果它总是“销毁和复制结构”,那么你想要'memcpy'的情况会更慢。 –

回答

1

你不应该创建虚拟对象只是做在下一步的任务,每次要一个副本。

特别是如果对象构造即使在默认构造时也很昂贵。

但确切原因副本c'tors,是过路的用户定义类型的值将是不可能的。然后我们将没有RAII。

至于赋值运算符,试想一下写类没有它。泛型(模板)代码将如何显示?

很多通用算法可以对仅仅是分配类工作,但没有该功能,你必须再次拨打其德TOR自己之前的“建设”的对象。

template <calls T) 
void assign(T& a, T& b) 
{ 
    a.~T(); 
    new (&a) (b); 
} 

基本上,穿类,他们的德TOR必须是公开的不合理的要求。或者他们必须让你的算法为friend

此外,这是不安全的。构造函数可能会抛出错误,这就是他们如何报告错误,并且如果T拷贝c'tor确实如此,那么在调用析构函数之后,a处于未定义状态。
问题是,你做出了将a从状态中解放出来的决定。如果我们使用了赋值运算符,那么赋值仍然会抛出,但它可能确保a尚未释放它的状态。

1

因为施工和任务是不同的事情。拷贝构造函数是参与,例如,当你按值传递一个参数,或构建与另一个对象:虽然分配是当你已经有对象和要复制一个到另一个

f(T o) { 
...} 

T object; 
f(object); // copy construction to pass the argument 
T object2(object); // construct a T from another T 

T object; 
... 
T object2; 
... 
object = object2; 

这些事情发生在不同种类的表达式上。

0

这里有两种不同的情况,

  • 初始化一个新的对象与现有对象的内容(1)现有的对象的另一现有对象
  • 复制/传送内容(2 )

有不同的场景中(1)是适用的,其中(2)适用。它们不一样。例如,如果我们想要共享具有相同类型的另一个对象(shared_ptr就是一个很好的例子)拥有对象的资源(例如内存)的所有权,我们需要在该类上实现的适当的copy-assignment运算符。

因此,我们需要为复制构建和复制分配做准备。

1

因为它们是不同的东西。

当你想构造从另一个新的对象将被调用复制ctor。

当您想从另一个对象中分配一个现有对象时,将调用赋值运算符,这意味着您可能需要在执行赋值之前销毁/释放现有对象保留的某些资源。

相关问题