我应该重置Destructor中的原始成员变量
Should I reset primitive member variable in destructor?
请参阅以下代码,
class MyClass
{
public:
int i;
MyClass()
{
i = 10;
}
};
MyClass* pObj = nullptr;
int main()
{
{
MyClass obj;
pObj = &obj;
}
while (1)
{
cout << pObj->i; //pObj is dangling pointer, still no crash.
Sleep(1000);
}
return 0;
}
OBJ一旦范围出来。但是我在VS 2017中进行了测试,即使使用后,我也没有崩溃。
重置int成员varialbe i
?
在对象被破坏后访问成员是未定义的行为。它可能看起来是一个很好的好方法调试器。
然而,这个想法有缺陷和矮小的系统:
- 所有班级都需要进行比赛,而不是专注于创建正确的代码开发人员将花费时间(开发时间和运行时)进行毫无意义的更改。
- 编译器发生相当聪明,可以检测到不需要变化。由于正确的程序无法检测到是否进行了更改,因此可能根本无法进行更改。此效果是安全应用程序的实际问题,例如,应该从内存中删除密码,因此无法读取该密码(使用某些不可规定的均值)。
- 即使值设置为特定值,内存也将重复使用并且值被覆盖。尤其是在堆栈上的对象中
- 即使重置值,您也一定会看到"崩溃":崩溃是由设置的东西引起的,以防止某些事物无效。在您的示例中,您将在堆栈上访问
int
:从CPU的角度来看,堆栈将保持访问,充其量将获得意外的值。使用不寻常的指针值通常会导致崩溃,因为内存管理系统试图访问未映射但不能保证的位置:在繁忙的32位系统上,几乎所有内存都可能正在使用。也就是说,试图依靠被检测到的未定义行为也是徒劳的。
相应地,最好使用良好的编码实践,避免立即悬挂参考并专注于使用这些习惯。例如,我始终在成员初始化列表中初始化成员,即使在极少数情况下,它们最终会在构造函数的正文中变化(即,您'D将您的构造函数写为MyClass(): i() {}
)。
作为调试工具,它 May 可以合理地替换分配函数(理想情况下是分配器对象,但可能是全局operator new()
/operator delete()
和带有一个版本,该版本不会很快发出发布的内存和内存和取而代之的是,用可预测的模式填充已发布的内存。由于这些操作减速了程序,您只会在调试构建中使用此代码,但是一次实现一次,并且易于启用/在中央启用/禁用,因此值得付出努力。在实践中,我认为即使这样的系统也没有证明使用托管指针,并且对所有权和终生的适当设计避免了由于参考的大多数错误。
您给出的代码的行为不确定。不确定行为的部分情况正常工作,因此代码有效并不奇怪。代码现在可以正常工作,无论如何它可以根据编译器版本,编译器选项,堆栈内容和月球阶段而破裂。
因此,首先也是最重要的是避免到处悬而未决的指针(以及所有其他不确定的行为)。
如何清理变量在破坏者中,我找到了一个最佳实践:
遵循编码规则,使我免于访问未分配或破坏对象的错误。我无法用几句话来描述它,但是规则很普遍(请参阅此处和任何地方)。
分析人类(代码审查)或统计分析仪(例如Cppcheck或pvs-studio或其他)的代码,以避免使用类似于您上面描述的案例。
请勿手动调用
delete
,更好地使用scoped_ptr
或类似的对象寿命经理。当delete
合理时,我通常(通常)将删除后的指针设置为nullptr,以免自己脱离错误。使用尽可能罕见的指针。参考是首选。
当我的班级的对象在外面使用的对象时,我怀疑有人可以在删除后访问它,我可以将签名字段放入内部,将其设置为Destructor中的0xDead之类的东西,然后在Enter或所有公共方法中检查。在这里,请小心不要降低您的代码至无法接受的速度。
从示例到0或-1的所有这些设置i
之后,是冗余。至于我,这不是您应该集中注意力的事情。
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 如果包含引用成员的类中缺少原始变量,为什么它仍然可以访问?
- C :原始成员与继承成员的优先级
- 我如何检测类是否具有C 中的隐式构造函数和原始成员
- 从C 到C#调用INT []显示随机大数字,而不是原始数组成员
- 为原始指针、智能指针和值创建成员函数的编译时变体
- 我应该重置Destructor中的原始成员变量
- 从原始数据填充成员的正确方法是什么
- 是否应始终为具有原始指针成员的类中的深层复制指针定义复制构造函数
- C++ 如何确保复制构造函数不会修改原始对象的指针数据成员?
- 绑定C++成员变量:getter/setter 或原始指针
- 使复制的成员引用变量引用副本的成员,而不是原始成员的成员
- 拥有一个具有原始指针访问器的unique_ptr成员是不好的做法吗?
- 提升进程间托管共享内存原始指针作为类成员
- 如何在c++中查找和避免未初始化的原始成员
- 智能指针(unique_ptr)代替原始指针作为类成员
- 如何在模板类的成员中使用重载的原始exp
- C++,从同一原始对象复制的多个对象中成员指针的"耦合"
- 自动生成移动操作和原始指针成员