如何解决在析构函数里调用虚函数的问题

el_vr 2014-08-22 05:47:12
我现在的程序设计是:
在子类B里new一个worker传给父类A,
父类A会在析构函数里调用worker的清理函数。
但由于worker已经在子类B的析构函数里delete掉了,所以会出问题。

简单表述如下,问一下有什么办法解决。设计的目的是:让父类可以根据接口来调用工作函数、清理函数。

#include <iostream>

using namespace std;

class Worker{
public:
virtual void clean(){
cout << "base Worker" << endl;
}
};

class MyWorker: public Worker {
virtual void clean() {
cout << "MyWorker" << endl;
}
};

class A {
private:
Worker* w;
public:
void set_w(Worker* pw) {
w = pw;
}
~A() {
if (w != NULL) {
cout << "call w->clean()" << endl;
w->clean();
}
}
};

class B: public A {
private:
Worker* w;
public:
B() {
w = new MyWorker();
set_w(w);
}

~B() {
delete w;
}
};

int main() {
B* b = new B();
delete b;
}
...全文
128 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
ybjx111 2014-08-23
  • 打赏
  • 举报
回复
#include <iostream>
 
using namespace std;
 
class Worker{
  public:
    virtual void clean(){
      cout << "base Worker" << endl;
    }
};
 
class MyWorker: public Worker {
  virtual void clean() {
    cout << "MyWorker" << endl;
  }
};
 
class A {
  //private:
  protected:   
  Worker* w;
  public:
    void set_w(Worker* pw) {
      w = pw;
    }
  virutal ~A() {
    if (w != NULL) {
      cout << "call w->clean()" << endl;
     w->clean();
     delete w;
    }
  }
};
 
class B: public A {
  //private:
  //  Worker* w;
  public:
    B() {
      w = new MyWorker();
      set_w(w);
    }
 
  ~B() {
    //delete w;
  }
};
 
int main() {
  B* b = new B();
  delete b;
}
这样我感觉好点
el_vr 2014-08-23
  • 打赏
  • 举报
回复
引用 7 楼 zhuyf87 的回复:
Effective C++条款9:绝不在构造和析构函数中调用虚函数。 不过仔细看一下楼主的描述,根本的问题不在这 既然是子类new的worker,为什么非要父类clean呢? 个人感觉这个设计很糟糕,看不出什么好处。
是子类new的worker,父类要在析构函数里调用worker->clean(). 想了一下bbs2241的建议,可以吧new Worker的工作放到父类里作为虚函数,让子类来实现。这样new和delete都在父类完成。
zhuyf87 2014-08-23
  • 打赏
  • 举报
回复
Effective C++条款9:绝不在构造和析构函数中调用虚函数。 不过仔细看一下楼主的描述,根本的问题不在这 既然是子类new的worker,为什么非要父类clean呢? 个人感觉这个设计很糟糕,看不出什么好处。
FancyMouse 2014-08-23
  • 打赏
  • 举报
回复
你这是A和B之间对于w的所有权不明的问题,是设计问题,不是什么析构函数怎么调用虚函数的问题。
bobo_包子 2014-08-22
  • 打赏
  • 举报
回复
可以根据接口来调用工作函数、清理函数 1. 可以通过虚方法完成 2. 最好是谁new的 谁delete
el_vr 2014-08-22
  • 打赏
  • 举报
回复
想了想可以传递一个配置类从子类到父类。父类收到配置类后,调用配置类来生成需要的东西,并负责释放。
el_vr 2014-08-22
  • 打赏
  • 举报
回复
我刚刚想了一下,可以吧B is A,改为 B has A. 不知道还有什么别的解决办法吗。 如下设计B,其他地方不变:

class B {
  private:
    Worker* w;
    A* a;
  public:
    B() {
      a = new A();
      w = new MyWorker();
      a->set_w(w);
    }  

  ~B() {
    delete a;
    delete w;
  }
};
derekrose 2014-08-22
  • 打赏
  • 举报
回复
set pointer这种操作简直就是程序悲剧的开始

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧