从内存中删除对象后,什么值将具有作为指针的类成员

What value will have class member that are pointers after deleteing the object from memory?

本文关键字:指针 成员 删除 内存 对象 什么      更新时间:2023-10-16

我有这样的代码:

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_pointerAmemberPointerB是指向A的指针,是指向void (B::*Something)(A*,C)类事物的函数指针。不知何故,在代码中发生了这种情况:callback1()似乎是一个函数,它导致调用my_class_methodMyClass 类型的对象的析构函数。但是,由于函数执行未完成,因此应检查条件if以查找已破坏的对象。在调用之前callback1() member_pointerAmemberPointerB为 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.

如果由于某种原因必须是自删除回调,您可以做什么:

  1. 让我们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
        } 
    }
    
  2. 如果两个条件相互排除,请使用else if

    void my_class_method()
    {
        if (some_condition)
        {
          callback1();  //maybe calls "delete this"
        } 
        else if (member_pointerA && memberPointerB)
        {
          callback2(this); 
        }
    } 
    

    虽然从概念上讲,这可能是也可能不是相同的,但这是一个巨大的差异,因为如果第一个条件是错误的,那么第二个条件就会被评估,因此callback1并且不会发生自我删除。

  3. 如果两个回调的顺序无关紧要,请更改它,以便callback1是可以执行的最后一件事:

    void my_class_method()
    {
        if (member_pointerA && memberPointerB)
        {
          callback2(this); 
        }
        if (some_condition)
        {
          callback1();  //maybe calls "delete this"
        } 
    } 
    
对象

删除后指针的值未定义。我经常使用宏来调用delete运算符,然后将零分配给指针。