Undefined behaviour on reinitializing object via placement new on this pointer

巧了我就是萌 提交于 2019-12-05 04:31:24

I believe Elizabeth Barret Browning said it best. Let me count the ways.

  1. If Base isn't trivially destructible, we're failing to cleanup resources.
  2. If sizeof(Derived) is larger than the size of the dynamic type of this, we're going to clobber other memory.
  3. If Base isn't the first subobject of Derived, then the storage for the new object won't exactly overlay the original storage, and you'd also end up clobbering other memory.
  4. If Derived is just a different type from the initial dynamic type, even if it's the same size, than the object that we're calling foo() on cannot be used to refer to the new object. The same is true if any of the members of Base or Derived are const qualified or are references. You'd need to std::launder any external pointers/references.

However, if sizeof(Base) == sizeof(Derived), and Derived is trivially destructible, Base is the first subobject of Derived, and you only actually have Derived objects... this is fine.

Regarding your question

...Because I assume due to its pre-allocation std::vector must rely on placement-news and explicit ctors. And point 4 requires it to be the most-derived type which Base clearly isn't. And point 4 requires it to be the most-derived type which Base clearly isn't.

, I think the misunderstanding comes from the term "most derived object" or "most derived type":

The "most derived type" of an object of class type is the class with which the object was instantiated, regardless of whether this class has further subclasses or not. Consider the following program:

struct A {
    virtual void foo() { cout << "A" << endl; };
};

struct B : public A {
    virtual void foo() { cout << "B" << endl; };
};

struct C : public B {
    virtual void foo() { cout << "C" << endl; };
};

int main() {

    B b;  // b is-a B, but it also is-an A (referred  to as a base object of b).
          // The most derived class of b is, however, B, and not A and not C.
}

When you now create a vector<B>, then the elements of this vector will be instances of class B, and so the most derived type of the elements will always be B, and not C (or Derived) in your case.

Hope this brings some light in.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!