0

I have to create a function which overloads the = operator so that when you put object1 = object2; it'll copy over all the values inside object2 into object1.

My class looks like:

class foo { private: int max; int *val; size_t *listofVal; } 

And my overload function is declared as:

foo& foo::operator=(const foo& matrix); foo::foo(std::istream& s); //constructor 

how would I do this?

3
  • 2
    This looks like homework. What have you tried already? Commented Aug 30, 2011 at 10:54
  • @sasha i have tried making the private variables mutable but I think that is quite ugly. Commented Aug 30, 2011 at 10:56
  • SNpn: Your overloaded operator is a member of your foo class, and therefore has access to the private member data. Commented Aug 30, 2011 at 11:08

3 Answers 3

5

The best way to do this is by using Copy and Swap Idiom.
Also, note that if you feel the need of overloading the copy assignment operator then you also probably need to overload copy constructor as well as the destructor for your class.

Do have a look at Rule of Three.

Sign up to request clarification or add additional context in comments.

7 Comments

Note that Copy and Swap will give you the strong exception safety guarantee, which you may not need. Use CAS by default, but consider implementing an assignment operator with only the weak guarantee if you run into (profiled) performance issues.
@Mankarse: Why do you think that copy and swap will be non optimal?
@Martin, because copy and swap means that each primitive in the object has to be copied into a temporary and then assigned from that temporary into the assignee. This could be slow for a large object that do not own many external resources. You also lose opportunities to reuse memory that the assignee has already allocated. I think that most programs would not be significantly slowed down by these things, but it is worth knowing that there are correct alternatives to Copy and Swap.
@Mankarse: You need to do all the work anyway even if you do not use CAS. So it makes no difference. Write it out by hand there is no extra allocations it is just done into a box rather that into a list of local temporaries.
@Martin - struct With { char a[1000]; With& operator=(With o) {swap(o);} }; struct Without { char a[1000]; Without& operator=(Without const& o){a = o.a;} }; In the first example there is a copy into o, and then the cost of a swap. In the second example there is just a single assignment. If the cost of copying the data members significantly outweighs the cost of copying the owned resources, then copy and swap will be significantly slower.
|
1

Simply copying all the values is the default behaviour of the compiler supplied copy contructor. This is known as a "shallow-copy".

More elaborate behaviour is achieved by implementing your own constructor so that the objects (here values) pointed to by your reference are created anew in the copy.

foo::foo(std::istream& s) { max = s.max; val = new int; *val = s->val; listofVal = new size_t; *listofVal = s->listofVal; } 

would be one way of achieving that which is known as a "deep copy".

But as one of your members is called listofVal I rather feel you are doing something other than storing a single value at the memory address it points, in which case you should be holing a counter to the number of elements contained therein, which I will henceforth assume to be the field you call max. To copy the whole list, your copy constructor would then need to be:

foo::foo(std::istream& s) { max = s.max; val = new int; *val = s->val; listofVal = new size_t[max]; for (int i = 0; i < max; ++i) listofVal[i] = s->listofVal[i]; } 

Ravi, yes, the copy constructor is a proof of construct and despite breaking the "Rule Of Three" can be implemented before the other two. Here is the assignment operator.

foo& foo::operator=(const foo& matrix) { if (this != matrix) { max = matrix.max; val = new int; *val = matrix->val; listofVal = new size_t[max]; for (int i = 0; i < max; ++i) listofVal[i] = matrix->listofVal[i]; } } 

would be suitabe for object1 = object2; assignment. I tend towards the copy constructor approach.

The methods need to be members to access the private data so your class should be like

class foo { ///...///As before foo &operator=(const foo& matrix); }; 

Of course it needs a destructor but as it was not explicitly requested I didn't want to answer what wasn't asked.

Following on from the link to the Copy and Swap idiom, when the LHS may already contain data, for robust assignment you might consider:

foo& foo::operator=(const foo& matrix) { if (this != matrix) { val = new int; *val = matrix->val; size_t* newArray = new size_t[max]; int newMax = matrix.max; std::copy(matrix.listofVal, matrix.listofVal + max, newArray); if (listofVal) delete listofVal; listofVal = newArray; max = newMax; } } 

I would add that assigning local objects on the heap can cause memory leaks (if the method breaks before they are assigned to an object responsible for their deletion), but that is just a whole nother layer of parannoia when we have enough to do preserving class integrity.

5 Comments

I think you meant to define foo& foo::operator=(const foo& matrix)
@John are we allowed to do this even if they are private?
Additionally you must take care of pointers if memory is allocated for them in foo ctor. If it is so you must include checking of self-assignment to avoid memory corruption, otherwise memory will be released twice.
@SNpn, yes, you have indicated that they are members of your class foo. In that case you would need to declare them inside the class declaration/definition in the header.
Of course it needs a destructor but it seemed like to much work to write that as well when it was not explicitly requested.
-1

Googling for "C++ Assignment Operator" gives you this useful site ;-)

2 Comments

I think it is not useful an answer like that, you can find a lot of "bad teachers" in the web. That's why people post questions on this web site
I think researching this topic on one's own (not necessarily on the internet, but also in books) would have been possible, that's why I just posted a link. I guess I will refrain from doing so in the future.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.