今天比较郁闷,但仍然还是要坚持的,前几十年的经验告诉我,不坚持,不成功!不忍耐,不成功!
关于析构函数只讲两点:
POINT 11. 不要让异常从析构函数中跑掉,因为这样,就会导致你的程序脱离了自己的控制。
方法就是,在析构函数里加try...catch...,要么自己把自己的程序abort掉,或者把这个异常自己吞掉,不管能不能消化。至少自己还掌握着自己的生命。
因为不是所有的程序都会有机会产生异常,这里也只是说那些有很大风险产生异常的函数,还是需要以下这么做的。举例如下:
class A
{
A(){}
~A
{
try
{
exception();
}
catch(...)
{
std::abort; //abort yourself
//or log it and continue to do
...
}
}
private:
exception(){...};
}
POINT12, 不要在构造和析构函数里调用virutal函数
原因是,在构造和析构函数里调用virtual函数,是不会起到多态的效果的,比如在base class的构造函数里调用了一个virtual的函数fun(),实际上call的函数base class的fun()。为什么?因为创建derived class的对象时,它的构造顺序是先构造父类的,然后才是子类的,在构造父类对象时,子类那个成员变量和那些函数还都没有被初始化呢,编译器能找到的只有父类的fun()。
同理啊,在析构的时候也是一样的,因为首先析构了子类的对象,等call到父类析构的时候,能找到的fun()也只是父类的而已。
过程就是这样,所以不要试图在构造析构里使用多态的特性!
POINT13,关于重载=,请返回reference &,请注意自我赋值
我前面也讲过了,关于copy assignment,但那时只是将它声明,没有实现,现在我们来看如何实现和正确的实现。
对于这种情况 int x = y = z = 5; 我们可以看出,=的返回值是需要做左值的,另外由于pass by value与pass by reference,在OOC++中当然选择pass by reference,所以近乎我们可以得到一个标准的copy assignment声明式:
template <typename T>
T& operator = (const T& t) { ...; return *this; }
下面对于实现的部分进一步分析,上面看到,我返回的是return *this;但很有可能客户会做下面的操作:
t = t; //很白痴,那是一位这个看起来很明显而已
如果是这样的
T *pt1 = &t;
T *pt2 = &t;
*pt1 = *pt2; //这样就不太明显了吧
如果是下面这样
class baseClass{...}
class derivedClass {...}
void doSomething( baseClass& bc, derivedClass* pdc)
{ bc = *pdc; } //而这两个参数指向的是同一个对象,你还能那么明显的看出来吗?
所以,有必要避免以下这个问题,方法很简单,就是做个indentity test
class Bitmap { ... };
class T
{
public:
T & operator = (const T& t)
{
if(*this == t) return *this; //identity test
delete pBitmap;
pBitmap= new Bitmap(*t.pBitmap);
return *this;
}
private:
Bitmap* pBitmap;
}
ok,到现在为止解决了自身赋值的问题。但是,仍然还有一个异常安全性(exception safety)的问题。比如就是Bitmap出现了异常,可能是内存不足导致异常,所以,当返回*this后,pBitmap仍然还是无效的,所以我们还是要继续解决这个问题。
这种方法号称连自我赋值都可以避免了,可谓一箭双雕,如下:
T & operator = (const T& t)
{
Bitmap* pOri = pBitmap; //backup the original pointer
pBitmap= new Bitmap(*t.pBitmap); //create the new one
delete pOri ; //delete the old one
return *this;
}
不过我现在还是不明白这个就能防止exception了,只是先备份了一个指针,new Bitmap时出现异常,然后删除旧的bitmap对象,pBitmap不是还指在一个已经被删除的对象上吗??
虽然明天是端午节,有一个星期的假期,但我现在心情不好,没心情搞清这个问题了,目前只是知道exception safe很重要,以前基本没有注意过,也没有使用过。下次解释了... ...
一直在一个地方无谓的努力真是一种悲哀,你的视野越来越小,你的经历越来越少,你的年龄越来越大。现在的我就像一个平庸的小程序,每天都在这里循环着,一直没有退出过这个loop,都快6年了,我现在很需要一个break或者一个不会被catch的exception。这样你的生活就会大不同了,虽然还是会掉到另外一个循环中,但是条件和运行环境是不会一样的,努力加油,还有最后一个月的时间了!!!
本文探讨了析构函数中处理异常的重要性,强调了避免异常逃离析构函数的策略,包括使用try...catch...块进行异常捕获与处理。同时,文章指出在构造和析构函数内调用虚函数可能导致的多态性问题,并详细解释了如何通过复制成员变量来解决自我赋值问题,以及在实现时考虑异常安全性的必要性。
1691

被折叠的 条评论
为什么被折叠?



