This question is to confirm I understood the concept right and take expert opinion on the style of usages and possible optimization.
I am trying to understand \"plac
This is probably something for CodeReview.SE, let me comment your sourcecode a bit before I answer your questions.
A *obj1 = new A(21);
std::cout<<"Object allocated at "<~A();
You'd normally never call the destructor on a object not created with placement-new. In your case, you destruct the old one and construct a new one with placement-new. Even though this works, you should rather implement some reset functionality to reset your object instead of destructing and constructing a new one.
17 obj1->testFunction();
This is UB. You already destructed the object, you shouldn't call any methods on it.
18 A *obj2 = new(obj1) A(22);
19 obj1->testFunction();
20 obj2->testFunction();
This is okayish, note though that obj1 and obj2 is the exact same object.
21 delete(obj1);// Is it really needed now? Here it will delete both objects.. so this is not the right place.
Your comment is wrong. You're not deleting two objects, you're deleting one, more later.
22 obj1->testFunction();
23 obj2->testFunction();
This is - again - UB, don't call methods on a deconstructed or deleted object. To your questions:
member _a is dynamically allocated (with no placement new). So why it is getting same same address for obj1 & obj2. Is it just a coincidence?
Don't call them obj1 and obj2 because those two variables point to the same object, but yes, it is coincidence. After the first object got destructed and free'd this memory, the second one allocated the same amount of memory which was just freed and the allocator decided to give you the exact same memory.
is D'tor call on line 15 a good practice?
No, its not. There are very few examples why you'd need to call the destructor, one of them is that your object was created by placement-new. In your example this has no sideeffects because you construct a new object in the same place after deconstructing the old one and the new object is of the same type as the old one, otherwise this could break badly in some way.
Now a bit more about your comment after delete. Lets see what a new and a placement-new actually does.
A new does:
this) is set to the block of memory the allocator got.The delete does the opposite:
Now to the placement-new: The placement-new just skips the first step (allocating memory) and calls the constructor of that new object with this set to the address you passed. The opposite of placement-new is therefore just calling the destructor as there does not exist a placement-delete.
This means for your code, after you called the destructor, your first object died but you never gave the memory back, thats why you can construct a new object in that memory. Now when you call delete, the first object does not exist anymore, only the memory it used, but that same memory is now obstructed by the second object, therefore when you call delete you don't delete two objects, you delete only the second one (you deconstruct it and then deallocate the chunk of memory).
You can read more about the topic placement-new and when to call the destructor at isocpp's faq