[英]Copy Constructor and Overloaded Assignment?
任何人都可以在下面提到的代码中解释我的分配操作员。 我有
问题1 :为什么赋值运算符返回引用对象[我知道这用于类似这样的事情c1 = c2 = c3
,但这是如何工作的]
任务2 :我创建了动态指针tempName
但我没有释放内存,因此存在内存泄漏。 我怎么解决这个问题。 或者举个例子,如果你有。
任务3 :我已经在名称中指定了tempName
,因此如果我在返回之前删除tempName
,则name指向tempName
,然后会发生什么。
Contact& operator=( const Contact& rhs ) {
char* tempName = new char[ strlen( rhs. name ) + 1] ;
delete[ ] name;
name = tempName;
strcpy( name, rhs. name ) ;
age = rhs. age;
return *this;
}
当您返回对对象的引用时,您可以将其放在赋值的左侧以分配另一个值。 所以,我认为有两个原因。
(1)避免不必要的复制。
(2)C ++中赋值的默认行为,你可以这样做
a = (b = c)
要么
(a = b) = c
即使返回值,第一种形式也可以。 但是对于第二个,您必须返回对该值的引用,以使其行为与正常的C ++分配相同。 †
是的,它有内存泄漏。 除非,您删除析构函数中的name
。
name
和tempName
指向同一个地址。 因此,删除tempName
将删除指向的name
。 不要这样做。
而且,使用C ++,为什么你不使用std::string
而不是C风格的字符串,让std::string
来管理它的内存。
†当然,您可以违反C ++方式并为运营商提供自己的行为。 但不建议这样做。
避免不必要的复制。 即使你返回一个值,链接也会起作用,所以它并不是绝对必要的。 返回引用主要是模仿本机类型的赋值,其中编译器返回l值而不是r值。 甚至编译器生成的赋值运算符也返回引用。
您删除析构函数中的内存。
如果删除然后返回,则调用者将无法使用它。
在C ++中(如在C中),assignement返回一个值。 实际上a = b = c
只是: a = (b = c)
因为b = c
返回b = c
的新值。
这就是为什么要避免破坏语言语义的原因,分配操作必须在分配后返回对象的引用。
在失去对指针的访问权限之前必须释放内存。 一种简单的方法是封装到对象中的原始指针,并在析构函数(封装对象)中执行删除操作。 这就是std::unique_ptr
的原因。 但在此用例中, tempname
已受到对象的name
属性的影响。 只需删除Contact
析构函数中的name
。
this->name
似乎是一个原始指针,恰好指向新分配的tempname
。 如果在返回之前删除tempname
, this->name
将指向释放的内存=>它所谓的悬空指针。
链接赋值是一种语法,您可以一次为多个持有者分配值,如a = b = c
。 你可以这样理解: b=c; a=b;
b=c; a=b;
当它从右到左执行时它会叠加。 链接可以通过按值返回以及通过引用返回来实现。 现在回到你的问题“为什么参考?”。 参考用于优化。 按值返回时,将创建值的副本并将其发送回调用代码。 请考虑以下代码以便更好地理解:
class A { int _a; public: void setA(int a){ _a = a; } A() :_a(0){} A operator=(const A&);// here we are returning by value A& operator=(const A&);// here we are returning by reference. //Both support chaining but using reference avoids unnecessary copy };
您不必使用tempName分配内存,而是可以使用“name”本身。 请参阅以下代码段:
delete[ ] name;
char* name = new char[ strlen( rhs. name ) + 1];
由于在您的代码中(这不是理想的),name和tempName
指向相同的内存位置。 删除tempName
会导致name
堆损坏,这意味着当您尝试访问name
程序将中断。
我希望有所帮助。 评论进一步澄清。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.