清理后删除它

时间:2013-12-13 21:15:21

标签: c++ this destructor delete-operator

class BaseTest {
protected:
  virtual void finalizeParts() {
      delete m_part;
  };
public:
  int* m_part;

  BaseTest() {
    m_part = new int;
  }

  void finalize() {
    finalizeParts();
    delete this;
  }
};

class SubTest : public BaseTest {
protected:
  void finalizeParts() {
      BaseTest::finalizeParts();
      delete m_anotherPart;
  }
public:
  int* m_anotherPart;

  SubTest() {
    m_anotherPart = new int;
  }
};

SubTest* test = new SubTest();
test->finalize();

我在我的类的析构函数中避免虚函数调用时遇到了麻烦(我讨厌C ++强迫我首先执行此操作)。与基类中的常见清理策略相比,覆盖所有子类中的析构函数似乎非常不方便,使用一些可以在需要时覆盖的虚函数。作为一种解决方法,我正在考虑引入一个“最终确定”的方法。函数在我的基类中执行清理,最后调用'删除这个'。这可能是一个非常不寻常的解决方案,所以我想知道我是否以错误的方式接近这个问题,以及是否有一个更明显的方式来写“正确”的方法。 C ++中的析构函数。

3 个答案:

答案 0 :(得分:1)

如果您的对象聚合了管理其资源的其他对象(例如,考虑智能指针。一般原则称为RAII),那么根本不需要析构函数。

当然,你仍然需要每个这样的“经理”的解决方案,但由于需要关注的信息和资源较少,它应该更容易实现。

在你的情况下自我删除似乎是不好的方法,因为没有人会期望finalize释放对象的记忆(最不惊讶的原则)。虽然内部实现可能没问题(例如,我曾经在实现shared_ptr时做过delete this。也就是说,当资源管理器的计数器达到0时我就做了。但是这种行为无论如何都没有暴露给最终用户)

答案 1 :(得分:1)

你的做法是错误的。

使用虚拟析构函数,将调用基类的析构函数以及派生类的析构函数 - 因此您应该为每个派生类实现析构函数,这将只删除派生类的相关部分,并让基类的析构函数清除基类。

如果你有一个派生类链,那么将调用每个继承级别的析构函数 - 从大多数派生类到基类的顺序。

对于您的示例,所需要的只是:

class BaseTest {
public:
  virtual ~BaseTest () {
      delete m_part;
  };
  int* m_part;

  BaseTest() {
    m_part = new int;
  }
};

class SubTest : public BaseTest {
 public:
  virtual ~SubTest () {
      //~BaseTest() will be called automatically
      delete m_anotherPart;
  }
  int* m_anotherPart;

  SubTest() {
    m_anotherPart = new int;
  }
};

SubTest* test = new SubTest();
delete test;

答案 2 :(得分:0)

这对你来说更简单吗?

class BaseTest {
public:
  std::unique_ptr<int> m_part;

  BaseTest() : m_part(new int) {}
  virtual ~BaseTest() {}
};

class SubTest : public BaseTest {
public:
  std::unique_ptr<int> m_anotherPart;

  SubTest() : m_anotherPart(new int) {}
};

SubTest test;

或者就此而言,

class BaseTest {
public:
  int m_part;
};

class SubTest : public BaseTest {
public:
  int m_anotherPart;
};

SubTest test;

我认为你有XY problem。而不是向我们询问你已经做过的奇怪的重新实现 - 已经做了什么,请询问你在析构函数中调用虚函数时遇到的问题。