从内存中删除对象后,什么值将具有作为指针的类成员
What value will have class member that are pointers after deleteing the object from memory?
我有这样的代码:
class MyClass
{
typedef void (B::*F)(A*,C);
private:
A* member_pointerA;
F memberPointerB;
void my_class_method()
{
if (some_condition)
// call a callback Function
callback1();
if (member_pointerA && memberPointerB)
//call another function and pass this
callback2(this);
}
};
其中my_class_method
是一个类方法。 member_pointerA
和memberPointerB
是指向A
的指针,是指向void (B::*Something)(A*,C)
类事物的函数指针。不知何故,在代码中发生了这种情况:callback1()
似乎是一个函数,它导致调用my_class_method
的 MyClass
类型的对象的析构函数。但是,由于函数执行未完成,因此应检查条件if
以查找已破坏的对象。在调用之前callback1()
member_pointerA
和memberPointerB
为 NULL,但在调用之后,它们不知何故变得不为 NULL,并且程序崩溃。当我交换if
的位置时,不考虑if (member_pointerA && memberPointerB)
条件,因为两个指针都是空的。那么删除对象后,成员指针将其值从 NULL 更改为一些垃圾的解释是什么?
理解正确,callback1
删除调用它的对象,可能是通过调用堆栈下方某处的delete this;
。如果是这种情况,则在执行callback1
后,您可能不会对对象执行任何操作,这意味着对任何非静态成员函数的调用和使用任何非静态成员变量会产生未定义的行为:
void my_class_method()
{
if (some_condition)
// call a callback Function
callback1(); //maybe calls "delete this"
if (member_pointerA && memberPointerB) // use of member variables -> UB!!!
//call another function and pass this
callback2(this); // use of "this" -> UB!!!
}
注意:如果callback2
不是MyClass
的方法,则调用本身不是UB,但该函数肯定会尝试访问传递的对象,这将是UB,因为它可以访问已删除的对象。
最好的做法显然是没有回调来删除从中调用它的对象。在极少数情况下,自我删除是正确的做法,但它应该以非常明显的方式发生,而不是通过一些回调在幕后进行。
如果你必须在my_method
过程中删除对象,最明显的方法是在方法中调用delete this
而不是在某些回调中执行此操作。 然后callback1
可以返回一些值,指示是否应删除对象:
void my_class_method()
{
if (some_condition)
{
bool doSelfDelete = callback1();
if (doSelfDelete)
{
delete this;
return;
}
}
}
另一种可能性是使用智能指针(无论如何都是一个不错的选择(并通过累积shared_ptr
来延长对象的寿命this
:
void my_class_method()
{
auto self = shared_from_this(); //this is a standard library function, you need to derive from std::enable_shared_from_this<MyClass> to use it.
if (some_condition)
{
callback1(); //won't call a explicit delete since we are working with smart pointers, but may erase some shared_ptr to this object
// but since "self" is a shared_ptr too, it won't destroy this object
}
if (member_pointerA && memberPointerB) //ok
{
callback2(self); //since we don't use raw pointers any more...
}
} //now when self gets destroyed, "this" might get deleted as well.
如果由于某种原因必须是自删除回调,您可以做什么:
让我们
callback1
返回一些指示对象是否已被删除的内容(你不能让它设置成员变量,因为如果它已被删除,你就无法访问它(:void my_class_method() { if (some_condition) { bool isDeleted = callback1(); //maybe calls "delete this" if (isDeleted) return; //since isDeleted is not a member, you may use it } }
如果两个条件相互排除,请使用
else if
:void my_class_method() { if (some_condition) { callback1(); //maybe calls "delete this" } else if (member_pointerA && memberPointerB) { callback2(this); } }
虽然从概念上讲,这可能是也可能不是相同的,但这是一个巨大的差异,因为如果第一个条件是错误的,那么第二个条件就会被评估,因此
callback1
并且不会发生自我删除。如果两个回调的顺序无关紧要,请更改它,以便
callback1
是可以执行的最后一件事:void my_class_method() { if (member_pointerA && memberPointerB) { callback2(this); } if (some_condition) { callback1(); //maybe calls "delete this" } }
删除后指针的值未定义。我经常使用宏来调用delete
运算符,然后将零分配给指针。
- 如果基类包含双指针成员,则派生类的构造函数
- C++正确的指针成员初始化
- 是否可以使用智能指针成员设置具有另一个结构的结构?
- 为什么 operator() 处的指针成员不起作用?
- 更改队列指针成员的值需要在 C++ 中出现奇怪的错误
- 如何从另一个嵌套类中调用某个封闭类的嵌套类的函数指针成员的值?
- 结构对象的指针成员在传递给函数时被修改
- 参数的混合值,当我调用指针成员函数时
- 如何正确使用结构的共享指针成员?
- C++:私有类指针成员返回未定义的值
- 在函数中传递带有指针成员的结构是浅拷贝或深拷贝在 C 中
- 包含指针成员的嵌套结构
- 在 c++ 中,为什么 -> 被称为二进制中缀指针成员访问运算符?
- C++ 类指针成员行为奇怪(错误)
- 常量结构的指针成员
- 在类C++指针成员中
- 指针成员未在复制构造函数中初始化
- C++移动拥有指针成员的构造函数
- C++ 包含唯一指针成员变量的类的赋值运算符
- 如何使用 QPoint 指针成员对类进行排队和取消排队