河北建设厅网站上不去,手机如何登录wordpress,重庆专业网站建设公司哪家好,学校为什么要做网站我们知道#xff0c;有时会让一个基类指针指向用 new 运算符动态生成的派生类对象#xff08;类似接口的作用#xff09;#xff1b;同时#xff0c;用 new 运算符动态生成的对象都是通过 delete 指向它的指针来释放的。如果一个基类指针指向用 new 运算符动态生成的派生类…我们知道有时会让一个基类指针指向用 new 运算符动态生成的派生类对象类似接口的作用同时用 new 运算符动态生成的对象都是通过 delete 指向它的指针来释放的。如果一个基类指针指向用 new 运算符动态生成的派生类对象而释放该对象时是通过释放该基类指针来完成的就可能导致程序不正确。比如我们有一个钟表的基类 TimeKeeper用来计时而我们又有原子钟、水钟、腕表等一系列子类根据工厂模式我们可以定义一个 getAtomicClock函数来获得一个原子钟指针然后用基类指针TimeKeeper来指向它们其他子类也是同理这个TimeKeeper就相当于一个接口#include iostream
using namespace std;class TimeKeeper
{
public:TimeKeeper() {};~TimeKeeper() { cout TimeKeeper::destrutor endl; }
};// 原子钟
class AtomicClock : public TimeKeeper
{~AtomicClock(){ cout AtomicClock::destrutor endl; }
};
class WaterClock : public TimeKeeper {}; // 水钟
class WristClock : public TimeKeeper {}; // 腕表TimeKeeper* getAtomicClock()
{return new AtomicClock;
}TimeKeeper* getWaterClock()
{return new WaterClock;
}TimeKeeper* getWristClock()
{return new WristClock;
}int main() {TimeKeeper* ptk getAtomicClock();delete ptk;ptk getWaterClock();ptk getWristClock();
}如上面代码所示我们的三个工厂函数都是用的基类来指向的因为我们用的 new 来创建对象所以自然要用 delete 释放掉可是问题来了我们的ptk指针是用基类指向子类对象那么我们释放的时候是调用基类的析构还是子类的析构函数呢答案是调用基类的析构因为这里是静态联编在运行之前编译器只知道ptk是 TimeKeeper类型的自然是调用基类的析构但是我们实例化的是一个子类啊你调用基类的析构那子类中万一有一些基类没有的元素呢那岂不是没有被析构造成内存泄漏了因此为了解决这个问题就轮到了virtual析构函数的出场了我们只需要将基类的析构函数声明为虚析构即可virtual ~TimeKeeper() { cout TimeKeeper::destrutor endl; }发现基类和子类的析构函数都被调用了所以我们记住问题的关键在于在实现多态的时候堆区的内存可能会泄露这是要用虚析构如果是引用的话哪怕是多态不在堆区就不需要虚析构了AtomicClock ac;
TimeKeeper ptk ac;程序结束的时候依然会调用基类和子类的析构函数最后让我们再记一条原则类的设计目的如果不是作为基类使用或者不是为了具备多态性就不该声明虚析构函数