概念:
1.当在栈区创建一个类的对象的时候,会自动执行其构造函数,当函数代码块结束(经测试:不包括main函数结束),会自动执行其类的虚构函数。
2.当在堆中new出一个类的对象的时候,会自动执行其构造函数。但是函数代码块执行完毕,并不会掉用其析构函数。其析构函数执行必须经过delete来完成。但是在继承方面,倘若new一个派生类的对象,这个对象通过基类的指针指向这个无名的对派生类对象时,delete这个指针释放内存并不会执行子类的析构函数,而是仅仅执行基类的析构函数,这就将导致内存泄漏了。因此解决办法是将基类的构造函数设置为虚函数,因此当你通过delete访问基类的虚构函数,先会访问子类的虚构函数,这样就能完美释放所有类的对象占用的内存了。
【注】:
经过测试,在mac上面当我用基类的指针指向派生类new的对象竟然编译无法通过,或许这是一件值得庆幸的事情。
以下是测试代码:
//******************Base.hpp************************//
#ifndef Base_hpp
#define Base_hpp
#include <stdio.h>
#include <iostream>
class Base
{
public:
inline Base(){ std::cout<<"Base constrctor has been started!"<<std::endl;}
~Base(){std::cout<<"Base destructor has been started!"<<std::endl;}
};
class Drived
{
public:
inline Drived(){
std::cout<<"Derived constrctor has been started!"<<std::endl;
}
~Drived()
{
std::cout<<"Derived destrctor has been started!"<<std::endl;
}
};
#endif /* Base_hpp */
以下是主函数
//
// main.cpp
// destructor_demo
//
// Created by joey on 2018/12/1.
// Copyright © 2018 joey. All rights reserved.
//
#include <iostream>
#include "Base.hpp"
void test_destruc();
int main(int argc, const char * argv[]) {
// insert code here...
test_destruc();
return 0;
}
void test_destruc()
{
Base *p0 = new Base();
Drived *p = new Drived();
Base *p2 = new Drived(); //编译报错
delete p0;
delete p;
}