繁体   English   中英

复制构造函数和重载的赋值?

[英]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;
}

Q1。

当您返回对对象的引用时,您可以将其放在赋值的左侧以分配另一个值。 所以,我认为有两个原因。

(1)避免不必要的复制。

(2)C ++中赋值的默认行为,你可以这样做

a = (b = c)

要么

(a = b) = c

即使返回值,第一种形式也可以。 但是对于第二个,您必须返回对该值的引用,以使其行为与正常的C ++分配相同。

Q2。

是的,它有内存泄漏。 除非,您删除析构函数中的name

Q3。

nametempName指向同一个地址。 因此,删除tempName将删除指向的name 不要这样做。

而且,使用C ++,为什么你不使用std::string而不是C风格的字符串,让std::string来管理它的内存。


当然,您可以违反C ++方式并为运营商提供自己的行为。 但不建议这样做。

  1. 避免不必要的复制。 即使你返回一个值,链接也会起作用,所以它并不是绝对必要的。 返回引用主要是模仿本机类型的赋值,其中编译器返回l值而不是r值。 甚至编译器生成的赋值运算符也返回引用。

  2. 您删除析构函数中的内存。

  3. 如果删除然后返回,则调用者将无法使用它。

问题1:

在C ++中(如在C中),assignement返回一个值。 实际上a = b = c只是: a = (b = c)因为b = c返回b = c的新值。

这就是为什么要避免破坏语言语义的原因,分配操作必须在分配后返回对象的引用。

问题2 :

在失去对指针的访问权限之前必须释放内存。 一种简单的方法是封装到对象中的原始指针,并在析构函数(封装对象)中执行删除操作。 这就是std::unique_ptr的原因。 但在此用例中, tempname已受到对象的name属性的影响。 只需删除Contact析构函数中的name

问题3:

this->name似乎是一个原始指针,恰好指向新分配的tempname 如果在返回之前删除tempnamethis->name将指向释放的内存=>它所谓的悬空指针。

1:为什么赋值运算符返回参考对象

链接赋值是一种语法,您可以一次为多个持有者分配值,如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 };


2:我创建了动态指针tempName,但我没有释放内存,因此存在内存泄漏。 我怎么解决这个问题。 或者举个例子,如果你有

您不必使用tempName分配内存,而是可以使用“name”本身。 请参阅以下代码段:

delete[ ] name;

char* name = new char[ strlen( rhs. name ) + 1];

3:我已经在名称中指定了tempName,因此如果我在返回之前删除tempName,则name指向tempName,然后会发生什么。

由于在您的代码中(这不是理想的),name和tempName指向相同的内存位置。 删除tempName会导致name堆损坏,这意味着当您尝试访问name程序将中断。


我希望有所帮助。 评论进一步澄清。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM