samedi 4 mars 2017

Is it ok to call destructructor explicitly followed by placement new on a variable with fixed lifetime?

I know that calling destructor explicitly can lead to undefined behavior because of double destructor calling, like here:

#include <vector>

int main() {
  std::vector<int> foo(10);
  foo.~vector<int>();
  return 0;  // Oops, destructor will be called again on return, double-free.
}

But, what if we call placement new to "resurrect" the object?

#include <vector>

int main() {
  std::vector<int> foo(10);
  foo.~vector<int>();
  new (&foo) std::vector<int>(5);
  return 0;
}

More formally:

  1. What will happen in C++ (I'm interested in both C++03 and C++11, if there is a difference) if I explicitly call a destructor on some object which was not constructed with placement new in the first place (e.g. it's either local/global variable or was allocated with new) and then, before this object is destructed, call placement new on it to "restore" it?
  2. If it's ok, is it guaranteed that all non-const references to that object will also be ok, as long as I don't use them while the object is "dead"?
  3. If so, is it ok to use one of non-const references for placement new to resurrect the object?
  4. What about const references?

Example usecase (though this question is more about curiosity): I want to "re-assign" an object which does not have operator=.

I've seen this question which says that "overriding" object which has non-static const members is illegal. So, let's limit scope of this question to objects which do not have any const members.

Aucun commentaire:

Enregistrer un commentaire