假设我们有一个简单的结构:
struct RefCounters {
size_t strong_cnt;
size_t weak_cnt;
RefCounters() : strong_cnt(0), weak_cnt(0) {}
};
从实现的角度来看,析构函数RefCounters::~RefCounters
应该什么都不做,因为它的所有成员都有原始类型。这意味着如果使用析构函数的显式调用来销毁此类型的对象(但其内存不取消分配),那么我们将能够在对象死亡后正常使用其成员。 / p>
现在假设我们还有一些派生自RefCounters
的类。假设RefCounters
在Derived
类的基类中只出现一次Derived
。假设为类strong_cnt
的对象显式调用析构函数,但其内存不解除分配。在那之后访问成员weak_cnt
和Derived*
是否可以?
从实现的角度来看,它应该没问题,至少在没有涉及虚拟继承时。因为RefCounters*
可以静态转换为RefCounters
(向地址添加编译时常量偏移量),Derived
类的析构函数不应触及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";
的内存。
以下是代码示例:
SELECT DATEDIFF(last_day, first_day) + 1 AS days, name, score,
first_day, last_day
FROM (
SELECT
max(date_score) as last_day,
min(date_score) as first_day,
score,
name
FROM members
GROUP by score
) AS score
此类代码是否被C ++标准视为未定义的行为?是否有任何实际原因导致无法正常工作?可以通过微小的改变或添加一些约束来使其合法化吗?
P.S。据推测,这样的代码示例允许使用intrusive_ptr + weak_ptr组合,这样如果至少有一个weak_ptr仍然指向它,则总是可以从对象指针获得weak_ptr。 this question中的更多详细信息。
答案 0 :(得分:0)
我相信你的做法很糟糕。评论中有一个很好的链接,显示有关标准细节的争论。一旦有争议,不同的编译器很有可能以不同的方式实现这个细节。更。相同的编译器可能会将其实现从一个版本更改为另一个版本。
你使用各种黑暗角落的次数越多,就越有可能遇到问题。
底线。有什么愿意实现的?为什么不能使用普通的C ++语言功能来做到这一点?