简体   繁体   English

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

[英]Copy Constructor and Overloaded Assignment?

Can anybody explain me Assignment Operator in below mention code. 任何人都可以在下面提到的代码中解释我的分配操作员。 I have 我有

Ques 1 : Why that assignment operator return Reference Object [I know this is used for something like this c1 = c2 = c3 , But how this is work] 问题1 :为什么赋值运算符返回引用对象[我知道这用于类似这样的事情c1 = c2 = c3 ,但这是如何工作的]

Quest 2 : I have created dynamic pointer tempName but I've not release the memory, so there is a memory leak. 任务2 :我创建了动态指针tempName但我没有释放内存,因此存在内存泄漏。 How I can resolve that. 我怎么解决这个问题。 Or give me example if you have. 或者举个例子,如果你有。

Quest 3 : I have assigned tempName in name, so name is pointing to tempName if I delete tempName before the return, then what will happen. 任务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. Q1。

When you return a reference to an object, then you have the ability to put it in the left side of an assignment to assign another value. 当您返回对对象的引用时,您可以将其放在赋值的左侧以分配另一个值。 So, I see two reasons for it. 所以,我认为有两个原因。

(1) Avoid an unnecessary copy. (1)避免不必要的复制。

(2) Default behaviour of assignment in C++, you can do (2)C ++中赋值的默认行为,你可以这样做

a = (b = c)

or 要么

(a = b) = c

The first form is OK even with returning the value. 即使返回值,第一种形式也可以。 But for the second one, you must return a reference to the value to have a behaviour as same as normal C++ assignments. 但是对于第二个,您必须返回对该值的引用,以使其行为与正常的C ++分配相同。

Q2. Q2。

Yes, it has memory leak. 是的,它有内存泄漏。 Unless, you delete the name in the destructor. 除非,您删除析构函数中的name

Q3. Q3。

name and tempName are pointing to the same address. nametempName指向同一个地址。 So, deleting tempName will delete what name is pointing to. 因此,删除tempName将删除指向的name Don't do it. 不要这样做。

Moreover, using C++, why you don't use std::string instead of C-style strings and let the std::string to manage its memory. 而且,使用C ++,为什么你不使用std::string而不是C风格的字符串,让std::string来管理它的内存。


Of course you can disobey C++ ways and have your own behaviours for operators. 当然,您可以违反C ++方式并为运营商提供自己的行为。 But it's not recommended. 但不建议这样做。

  1. To avoid an unnecessary copy. 避免不必要的复制。 Chaining would work even if you return a value, so it's not strictly necessary. 即使你返回一个值,链接也会起作用,所以它并不是绝对必要的。 Returning a reference is mainly to mimic assignment of native types where the compiler returns an l-value rather than an r-value. 返回引用主要是模仿本机类型的赋值,其中编译器返回l值而不是r值。 Even the compiler generated assignment operator returns a reference. 甚至编译器生成的赋值运算符也返回引用。

  2. You delete the memory in the destructor. 您删除析构函数中的内存。

  3. If you delete and then return, the caller won't be able to use it. 如果删除然后返回,则调用者将无法使用它。

Question 1 : 问题1:

In C++ (as in C) an assignement returns a value. 在C ++中(如在C中),assignement返回一个值。 In fact a = b = c is simply : a = (b = c) because b = c returns the new value of b. 实际上a = b = c只是: a = (b = c)因为b = c返回b = c的新值。

That's the reason why to avoid breaking language semantics, the assignement operation must return a reference to the object after assignement. 这就是为什么要避免破坏语言语义的原因,分配操作必须在分配后返回对象的引用。

Question 2 : 问题2 :

You must release memory before loosing access to the pointer. 在失去对指针的访问权限之前必须释放内存。 One simple way is to encapsulate to raw pointer in an object and do the delete in the destructor (of the encapsulating object). 一种简单的方法是封装到对象中的原始指针,并在析构函数(封装对象)中执行删除操作。 That's why std::unique_ptr is for. 这就是std::unique_ptr的原因。 But in this use case, tempname has been affected to the name attribute of the object. 但在此用例中, tempname已受到对象的name属性的影响。 Simply delete the name in Contact destructor. 只需删除Contact析构函数中的name

Question 3 : 问题3:

this->name seems to be a raw pointer that happens to point to newly allocated tempname . this->name似乎是一个原始指针,恰好指向新分配的tempname If you delete tempname before the return, this->name will point to freed memory => what it called a dangling pointer. 如果在返回之前删除tempnamethis->name将指向释放的内存=>它所谓的悬空指针。

1: Why that assignment operator return Reference Object 1:为什么赋值运算符返回参考对象

Chaining assignment is the syntax where you assign values to multiple holders at once like a = b = c . 链接赋值是一种语法,您可以一次为多个持有者分配值,如a = b = c You can understand it this way: b=c; a=b; 你可以这样理解: b=c; a=b; b=c; a=b; as it executes from right to left it stack. 当它从右到左执行时它会叠加。 Chaining can be achieved by returning by value as well as by returning by reference. 链接可以通过按值返回以及通过引用返回来实现。 Now back to your question "why reference?". 现在回到你的问题“为什么参考?”。 References are used for optimization. 参考用于优化。 When you return by value a copy of the value is created and send back to the calling code. 按值返回时,将创建值的副本并将其发送回调用代码。 Consider the code below for better understanding: 请考虑以下代码以便更好地理解:

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: I have created dynamic pointer tempName but I've not release the memory, so there is a memory leak. 2:我创建了动态指针tempName,但我没有释放内存,因此存在内存泄漏。 How I can resolve that. 我怎么解决这个问题。 Or give me example if you have 或者举个例子,如果你有

You don't have to allocate memory with tempName, instead you can use 'name' itself. 您不必使用tempName分配内存,而是可以使用“name”本身。 Refer to below code snippet: 请参阅以下代码段:

delete[ ] name;

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

3: I have assigned tempName in name, so name is pointing to tempName if I delete tempName before the return, then what will happen. 3:我已经在名称中指定了tempName,因此如果我在返回之前删除tempName,则name指向tempName,然后会发生什么。

Since in your code(which is not ideal) name and tempName are pointing to same memory location. 由于在您的代码中(这不是理想的),name和tempName指向相同的内存位置。 Deleting tempName will cause a heap corruption for name which means when you will try to access name program will break. 删除tempName会导致name堆损坏,这意味着当您尝试访问name程序将中断。


I hope that helped. 我希望有所帮助。 Comment for any further clarification. 评论进一步澄清。

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

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