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

时间:2015-04-27 06:09:56

标签: c++ operator-overloading copy-constructor assignment-operator

任何人都可以在下面提到的代码中解释我的分配操作员。我有

问题1 :为什么该赋值运算符返回引用对象[我知道这用于此类c1 = c2 = c3,但这是如何工作的]

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

任务3 :我已在名称中指定了tempName,因此如果我在返回前删除tempName,则名称指向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;
}

4 个答案:

答案 0 :(得分:2)

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 :(得分:1)

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

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

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

答案 2 :(得分:0)

问题1:

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

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

问题2:

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

问题3:

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

答案 3 :(得分:0)

1:为什么赋值运算符返回引用对象

链接分配是一种语法,您可以像1 2 1-[( 3 1-[({ 4 1-[({5-[ 5 1-[({5-[( 4 1-[({5-[(4'-cyanobiphenyl-4-yl) 3 1-[({5-[(4'-cyanobiphenyl-4-yl)oxy] 2 1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl} 1 1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy) 0 1-[({5-[(4'-cyanobiphenyl-4-yl)oxy]pentyl}oxy)carbonyl] Level 0 has reached testing ends' 一样将值分配给多个持有者。你可以这样理解它:a = b = c因为它从右到左执行它堆叠。链接可以通过按值返回以及通过引用返回来实现。 现在回到你的问题“为什么参考?”。参考用于优化。按值返回时,将创建值的副本并将其发送回调用代码。 请考虑以下代码以便更好地理解:

b=c; a=b;

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

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

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 };

delete[ ] name;

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

由于您的代码(不理想)名称和char* name = new char[ strlen( rhs. name ) + 1]; 指向相同的内存位置。删除tempName会导致tempName的堆损坏,这意味着当您尝试访问name时,程序将会中断。

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