So I was going through a piece of text in C++ and came across the following piece of code:
example& assign(const example& source)
new (this) example(source);
Okay so I am trying to decode what this function assign is doing. What I have understood yet:
The function takes a constant reference of instance of the class and returns a reference to the class.
if block, firstly the destructor is called for the current instance (As far as I know, current object is destroyed and memory is freed).
Now the main question:
new (this) example(source)
This line is troubling me. What is happening here? If I am asked to guess, I would say that a new object is being created and is assigned as the current object, as I can infer from
Can anyone clear this up? How exactly are things going on here?
Is this kind of method safe? (If allocation is happening dynamically, programmer will have to deallocate it in future manually)
Best How To :
What you are seeing is an attempt at code-reusage. The idea is to use the copy constructor to implement the assignment operator (or, in this case an assignment function).
First, to get rid of the easy stuff:
if ensures that a self assignment (e.g.
x.assign(x)) is being handled correctly. This is necessary since the implementation relies on the fact that changing
*this does not change
source. By comparing
this to the address of the other object, this does test the objects for equality, but for sameness.
The function is missing a
return *this;, but you probably noticed that already.
Now to the two remaining lines:
Explicitly calls the destructor of the class
example. After that line the
this pointer no longer points to an object, but to uninitialized memory of
new (this) example(source);
Is the so-called placement new, which does not allocate memory, but simply creates a new
example at the location pointed to by
this by calling its copy constructor. In a way this is the syntax to explicitly call a constructor w/o allocating any memory.
Note that this reuses the memory that
*this held previously, no matter where that is: It could even be e.g. a
virtual base of an element of a dynamically allocated array...
As to the safety: In practice this is safe (although ugly and possibly not very efficient) as long as neither the constructor nor destructor throw. However, you can run into problems when deriving from a class that attempts to be sneaky like that.
If you want to know the simplest way to write an assignment operator/function that reuses the copy constructor, check this question, which basically boils down to:
example& assign(example source)
The most important differences:
- It utilizes a move constructor where applicable.
- This code is exception safe if the copy/move constructors and
swap are exception safe (which they should always be).
- It is slightly less efficient for self-assignment, since it will perform the copy, instead of recognizing a self-assignment.