让我们用一个例子开始:
#include <cstdio>
struct Base { virtual ~Base() {} virtual void foo() = 0; };
struct P: Base { virtual void foo() override { std::printf("Hello, World!"); } };
struct N: Base { virtual void foo() override {} };
void magic(Base& b);
// Example implementation that changes the dynamic type
// {
// void* s = dynamic_cast<void*>(&b);
// b.~B();
// new (s) N();
// }
int main() {
std::aligned_storage<sizeof(P), alignof(P)> storage;
void* s = static_cast<void*>(storage);
new (s) P();
Base& b = *static_cast<Base*>(s);
magic(b);
b.foo();
}
什么,按照标准,应该b.foo()
打印?
个人观点:这是不确定,因为b
后,我们在销毁实例了陈旧的magic
。 在这种情况下,会替换b.foo()
通过static_cast<B*>(s)->foo()
使这合法吗?
所以,现在我们有一个例子,可能(或不)是合法的,在眼前对我们所有人来说standardistas更普遍的问题是,是否改变了动态类型的对象是都不放过。 我们已经知道,C ++编译器可重复使用的存储(幸运的),所以这是一个有点棘手。
这个问题似乎是理论上的,但是它有编译器直接应用:可以将编译器devirtualize b.foo()
到bP::foo()
在上面的程序?
因此,我在寻找:
- 关于我自己的小程序一个明确的答案(我不能想出一个)。
- 一个可能的例子(单个就足够了)的改变的动态类型的对象的一合法的方式。