[英]Using members of base class after destruction of derived class
假设我们有一个简单的结构:
struct RefCounters {
size_t strong_cnt;
size_t weak_cnt;
RefCounters() : strong_cnt(0), weak_cnt(0) {}
};
从实现的角度来看,析构函数RefCounters::~RefCounters
应该什么都不做,因为它的所有成员都有原始类型。 这意味着如果通过显式调用析构函数来销毁此类型的对象(但其内存未被释放),那么我们将能够在对象死亡后正常使用其成员。
现在假设我们有更多来自RefCounters
类。 假设RefCounters
在Derived
类的基类中只出现一次。 假设为Derived
类的对象显式调用析构函数,但不释放其内存。 之后可以访问成员strong_cnt
和weak_cnt
吗?
从实现的角度来看,它应该没问题,至少在没有涉及虚拟继承时。 因为Derived*
可以静态地转换为RefCounters*
(将编译时常量偏移量添加到地址),并且Derived
类的析构函数不应该触及RefCounters
的内存。
这是一个代码示例:
struct RefCounted : public RefCounters {
virtual ~RefCounted() {}
};
struct Base : public RefCounted {
int val1;
virtual void print();
};
struct Derived : public Base {
std::string val2;
virtual void print();
};
Derived *pDer = new Derived();
pDer->~Derived(); //destroy object
pDer->strong_cnt++; //modify its member
std::cout << pDer->strong_cnt << pDer->weak_cnt << "\n";
这些代码是否被C ++标准视为未定义的行为? 是否有任何实际原因导致无法正常工作? 可以通过微小的变化或添加一些约束来使其合法吗?
PS据说,这样的代码示例允许使用intrusive_ptr + weak_ptr组合,这样如果至少有一个weak_ptr仍然指向它,则总是可以从对象指针获得weak_ptr。 这个问题的更多细节。
我相信你的方法很糟糕。 评论中有一个很好的链接,显示有关标准细节的争论。 一旦有争议,不同的编译器很有可能以不同的方式实现这个细节。 更。 相同的编译器可以将其实现从一个版本更改为另一个版本。
你使用各种黑暗角落越多,遇到问题的可能性就越大。
底线。 有什么愿意实现的? 为什么不能使用普通的C ++语言功能呢?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.