简体   繁体   中英

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]

Quest 2 : I have created dynamic pointer tempName but I've not release the memory, so there is a memory leak. 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.

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.

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.

(2) Default behaviour of assignment in C++, you can do

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.

Q2.

Yes, it has memory leak. Unless, you delete the name in the destructor.

Q3.

name and tempName are pointing to the same address. So, deleting tempName will delete what name is pointing to. 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.


Of course you can disobey C++ ways and have your own behaviours for operators. 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. 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 :

In C++ (as in C) an assignement returns a value. In fact a = b = c is simply : a = (b = c) because b = c returns the new value of b.

That's the reason why to avoid breaking language semantics, the assignement operation must return a reference to the object after assignement.

Question 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. But in this use case, tempname has been affected to the name attribute of the object. Simply delete the name in Contact destructor.

Question 3 :

this->name seems to be a raw pointer that happens to point to newly allocated tempname . If you delete tempname before the return, this->name will point to freed memory => what it called a dangling pointer.

1: Why that assignment operator return Reference Object

Chaining assignment is the syntax where you assign values to multiple holders at once like a = b = c . You can understand it this way: 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. 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. 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.

Since in your code(which is not ideal) name and tempName are pointing to same memory location. Deleting tempName will cause a heap corruption for name which means when you will try to access name program will break.


I hope that helped. Comment for any further clarification.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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