C就地构造和随后的破坏:我如何获得正确的指针?
作者:互联网
免责声明:这是一个细致入微的C问题,与严格阅读C规范有很大关系.
在C中,使用就地构造的传统方法是:
void * pStorage = myPooledAllocationFunction ( /*pool number*/1 ) ; // allocate from pool number 1, for example
MyClass * p = new (pStorage) MyClass () ;
然而,重要的是要注意reinterpret_cast< void *> (p)不一定等于pStorage.
旁注:当我刚刚读到这个贴片时,我感到很沮丧,因为它真的只是说“请用这个额外的参数调用operator new”,而传统的使用它的方法恰好在C中有一个默认的实现.
我相信解除分配这个新创建的对象的传统方法是这样的:
p->~MyClass() ;
myPoolDeallocationFunction ( /*pool number*/1 ) ; // deallocate pool 1 in its entirety
这假设你能够做到这一点.但是如果你不是呢?如果你需要从p返回原始指针怎么办?
这有效吗?
p->~MyClass() ;
myPooledDeallocationFunction ( static_cast<void*> ( p ) ) ;
C规范(C 2003:5.2.9.10)规定使用static_cast从MyClass *转换为void *然后再转换回MyClass *是有效的.
还有另一个提及(C 2003:3.8.5)与此相关,指定您可以在调用析构函数之后但在释放内存之前,为该指针执行一组非常具体的操作.出于我们的目的,我们关心的是它包括将其转换为void *(这是有效的,因为旧指针“指向有效的内存”).
它没有说明该空隙*是否是用于就地构造的原始空隙*.
那么:如何从结果指针中获取用于就地构造的原始指针?
解决方法:
您可以使用dynamic_cast< void *>从基类检索原始指针.结果指针将始终指向派生程度最高的类,a.k.a.整个对象.
据我所知,pStorage和p是不同的地址是非法的.
标签:c,pointers,constructor,specifications 来源: https://codeday.me/bug/20190824/1708604.html