有人可以解释一下复制和分配之间的区别吗?
SomeClass a;
SomeClass b = a; // assignment
SomeClass c(a); // assignment
b = c; // copying
但有什么区别,为什么语言中有两种不同的结构?
答案 0 :(得分:3)
初始化仅在创建对象时发生一次。如果通过复制意味着调用复制构造函数,那么复制是一种初始化形式。分配可以发生任意次。
现在,举个例子,所有这些都是错的:
SomeClass a();
这声明了一个名为a
的方法,它不接受任何参数并返回一个对象SomeClass
。
SomeClass b = a; // actually copy constructor & initialization of b
SomeClass c(a); // same
如果a
是SomeClass
个对象,则这两个对象将进行初始化,并调用复制构造函数 - SomeClass::SomeClass(const SomeClass&)
。它们是等价的。
b = c; // assignment
如果c
是SomeClass
个对象,则此是分配。它呼叫SomeClass::operator =(const SomeClass&)
。
答案 1 :(得分:2)
这是初始化(但它调用了复制构造函数):
SomeClass b = a;
这就是:
SomeClass c(a);
这是作业:
b = c;
SomeClass a();
答案 2 :(得分:1)
初始化初始化以前未初始化的对象。另一方面,赋值会覆盖已初始化的对象,并且可能必须破坏现有状态。这些是不同的操作;虽然它们通常对LHS上的对象具有相同的结果,但它们在语义上并不等同。
答案 3 :(得分:1)
复制是通过复制现有对象的内容来初始化新对象,赋值是用其他对象的内容覆盖现有对象 - 两者是非常不同的东西。特别是,这个
SomeClass a;
SomeClass b = a;
是复制初始化 - 您正在使用
形式的语法复制a
以创建名为b
的新SomeClass
T x = y;
这具有调用SomeClass
的复制构造函数的效果(假设有一个并且可以访问)。编译器生成的默认复制构造函数将执行a
的成员副本;您可以根据需要用自己的替换,例如
SomeClass(const SomeClass& rhs)
: x(rhs.x)
{}
(请注意,这是一个非常无聊的例子,因为它只是执行默认的成员复制构造函数。)
继续,这个
SomeClass c(a);
使用复制构造函数直接初始化。它通常具有与上述相同的效果,但值得一读:
http://www.gotw.ca/gotw/036.htm
另外,请看这里:
http://www.gotw.ca/gotw/001.htm
你的最后一个案例,即
b = c;
是作业。这种语义一般应该是用b
的内容覆盖c
(尽管有些东西,比如std::auto_ptr
,有奇怪的赋值语义,所以要注意)。要实现自己的赋值运算符,你可以编写类似这样的东西(请注意,这是一个非常无聊的例子,因为它只是执行默认的成员赋值运算符):
SomeClass& operator=(const SomeClass& rhs)
{
x = rhs.x;
return *this;
}
然而,在实践中,在这种情况下你必须要小心异常安全性,这会导致像实现赋值运算符的流行的复制和交换习惯用法。见这里: