作者minazukimaya (水无月真夜)
看板C_and_CPP
标题Re: [问题] 多型的自动回收
时间Thu Oct 8 03:04:10 2009
※ 引述《yoco315 (眠月)》之铭言:
: 不要 = ="
: 既然资源是在 D 配的,D 要自己处理,不要给 B 管
: 所以这边改成这样
: virtual ~Base() {} // 虾米都不做
: : class Derived {
: : virtual void doClose() {
: : // ...
: : }
: 然後 D 加上解构子
: virtual ~Derived () { // 我自己来 XD
: D::doClose(); // ~B() 不能呼叫虚拟函数
: } // 我自己呼叫应该没问题吧???
: 还是我哪边错惹??????????
如果我的理解没错
原po他希望的是 Derived里面有个function负责relase资源
但是在错误使用(delete 前忘了呼叫close的时侯)能够自动释放
而且重要的是,希望能在Derived的设计者「忘了」在dtor呼叫doClose的时侯
只要是从Base class继承出来的class都能自动的去呼叫doClose
後面这就是重点了 因为Base和Derived的设计者有可能是不同人
可能document没写清楚 又或者单纯忘记了 总之因为种种原因
原po希望能在Base class里就自动的有机制去处理这件事..
所以现在的问题是:唯一在物件销毁时会自动执行的只有dtor
但是dtor中又不能呼叫virtual function
解决方法也就很直观了..那就是写成两个class 也就是把介面和实作分开来就好了
就像
#1Ap2yPNw提到的那样 刚好有个design pattern叫作bridge..
这有两种写法 动态多型的写法就像前述文章那样
class Base {
BaseImpl* pImpl;
public:
void open() { pImpl->doOpen(); }
void close() { pImpl->doClose(); }
void someOperation() { pImpl->someOperation(); }
~Base() { content->doClose(); delete pImpl; }
}
class BaseImpl {
friend Base;
virtual void doOpen()= 0;
virtual void doClose()= 0;
void someOperation() {};
}
如此这般 Base只提供一个操作的介面
实际的动作是委托给BaseImpl进行的
这样Derived class只要继承BaseImpl 自然就能成为一个Base的实作体
静态多型的写法是像下面这样
template <typename T>
class BaseInterface {
T impl;
public:
void open() {
impl._open();
}
void close() {
impl._close();
}
void someOperation() {
impl._someOperation();
}
~BaseImpl() {
impl._close();
}
}
class DerviedImpl { //implematation here };
typdef BaseInterface<DerivedImpl> Derived;
静态多型的方法可以省掉virtual function的呼叫成本
当然缺点就是没办法在run-time改变型别
不过如果以原po的需求:管理资源open和close的class集来说
应该不会要用动态多型..所以後者是比较建议的方法
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.32.13.219
※ 编辑: minazukimaya 来自: 114.32.13.219 (10/08 03:06)
1F:推 legnaleurc:没错,我完全就是这个意思 XD 10/08 12:17
2F:→ legnaleurc:不过我的确需要用到动态多型,因为 subclasses 的部分 10/08 12:18
3F:→ legnaleurc:是用 plugins 的方式 dynamic load 进来 10/08 12:18
4F:→ legnaleurc:看来必须要考虑是否值得为了这个举动增加class的复杂度 10/08 12:19