当我在阅读。
赋值运算符和复制构造函数有什么区别?
的时候,在这里。赋值运算符和复制构造函数有什么区别?
的时候,看到了下面的例子。
A aa;
A a = aa; //copy constructor
与..:
A aa;
A a;
a = aa; // assignment operator
我的问题是,为什么我们需要赋值操作符?我的意思是,在这种情况下,使用复制构造函数会更有效率,同时它也能完成同样的工作。
谁能举一个实际的例子,说明在使用赋值操作符时,不能用复制构造函数来代替?
当你想在一个值已经被构造后改变它时,你需要赋值。比如说
std::map
std::vector
.这样的例子几乎可以无休止地列举下去。但在你的例子中,确实可以简单地避免使用转让。
在你的例子中,确实可以简单地避免使用转让。抄写员 只被调用一次--在对象初始化的时候。当copy构造函数被调用时,它为变量分配一个新的内存块,然后将其分配给另一个对象。
但在 赋值构造函数只有一个对象中的字段值会被复制到另一个对象中,并且 当调用赋值构造函数时,会分配相同的内存。. 这就是复制构造函数和赋值构造函数的主要区别,复制构造函数为两个对象,即新创建的目标对象和源对象分别分配内存。赋值运算符为新创建的目标对象和源对象分配相同的内存位置。
复制构造函数在对象的生命周期中只被调用一次,那是在它的声明期间被初始化的情况下。每隔一段时间,当你将其他对象分配给它时,分配构造函数就会被调用。
是的,有一个著名的,赋值操作符不能被复制构造函数取代。
std::vector <int> f();
void g(){
decltype(auto) v = f() = f();
v.push_back(10); //boum undefined behaviour.
//without the non ref qualified copy assignment operator you
//could not have the pleasure to have undiscoverable UB in your code.
}
非ref限定的赋值操作符和预增和预减迭代操作符 是标准库提供的产生悬空引用的最好机会。
理论上任何复制赋值都可以用调用destructor后再调用复制构造函数来代替,因为构造函数不负责为新实例分配内存。实际上,你可以使用position new操作符调用构造函数而不分配任何内存。
但是,复制赋值比复制构造函数还是很有意思的,你认为复制构造函数性能更强的假设是错误的。
复制赋值和构造函数之间最大的区别在于,在赋值中,你可以依靠内存已经初始化的事实。在最好的情况下,这种预初始化并没有提供任何好处,复制构造函数和复制赋值一样具有性能。在其他情况下,复制赋值会从中受益,并且比构造函数的性能更高。
而且你可以加上调用destructor的成本,复制构造函数比赋值变得更没意思。