C++中,组合类,类的析构函数调用顺序

// test4.cpp : 定义控制台应用程序的入口点。
//    1.声明一个CPU类,包含等级rank,频率frequency,电压voltage等属性,有两个共有函数
//    stop 和ran。
//    其中,rank为枚举类型CPU_Rank,声明为enum CPU_Rank{p1=1,p2,p3,p4,p5,p6,p7},frequency为单位
//    MHz整数,voltage是浮点型电压值。
//2.声明一个RAM类,CDROM类。为实验四下半部分基于类的组合来构建Computer类打下基础。
//    提示:1.RAM类的主要参数包括:容量。类型和主频;类型建议用枚举类型(DDR4/DDR3/DDR2...)。
//         2.CD_ROM类的主要参数包括:接口类型、缓存容量、安装方式;
//         接口interface类型建议用枚举类型(SATA、USB...),安装install方式建议用枚举类型(external/built-in)。
//

#include "stdafx.h"
#include
using namespace std;

enum CPU_Rank{p1=1,p2,p3,p4,p5,p6,p7};//初始值为1,后面一次递增
class CPU{
private: //声明cpu类的属性,数据成员
    CPU_Rank rank;//等级
    int frequency;//频率
    float voltage;//电压
public:
    //带有参数的CPU类的构造函数
    CPU (CPU_Rank r, int f, float v){
        rank = r;
        frequency = f;
        voltage = v;
        cout<<"Creat a CPU构造函数!\n";
    }
    //析构函数
    ~CPU(){cout<<"release a CPU析构函数!\n";}

    //函数成员
    //外部接口函数,外部访问私有成员的接口
    CPU_Rank GetRank()const{return rank;}
    int GetFrequency()const{return frequency;}
    float GetVoltage()const{return voltage;}

    void SetRank(CPU_Rank r){rank = r;}
    void SetFrequency(int f){frequency = f;}
    void SetVoltage(float v){voltage = v;}
    void run(){cout<<"CPU开始运行\n";}//成员函数与正常定义函数相同;返回值类型,函数名,含参数
    void stop(){cout<<"CPU停止运行\n";}

};

enum RAM_Type{DDR2=2,DDR3,DDR4 };
class RAM{
private:
    enum RAM_Type type;
    unsigned int frequency;//MHz
    unsigned int capacity;//GB
public:
    RAM(RAM_Type t, int f, int c){
        capacity = c;
        frequency = f;
        type = t;
        cout<<"creat a RAM构造函数\n";
    }
    ~RAM(){cout<<"release a RAM析构函数\n";}
    //成员函数
    //外部接口
    //获取3个私有成员
    RAM_Type GetType()const{return type;}
    unsigned int GetFrequency()const{return frequency;}
    unsigned int GetCapacity()const{return capacity;}
    //设置3个私有成员值
    void SetType(RAM_Type t){type=t;}
    void SetFrequency(unsigned int f){frequency = f;}
    void SetCapacity(unsigned int c){capacity = c;}

    void run(){cout<<"run the RAM\n";}
    void stop(){cout<<"stop the RAM\n";}
};

enum CD_ROM_Install{external, built_in};//安装
enum CD_ROM_Interface{STAT, USB};//接口interface
class CDROM{
private:
    CD_ROM_Install install;
    unsigned int cache_size;//MB
    CD_ROM_Interface interf;
public:
    //构造函数
    CDROM(CD_ROM_Install ist,unsigned int s, CD_ROM_Interface itf){
        install = ist;
        cache_size = s;
        interf = itf;
        cout<<"creat a CDROM 构造函数!\n";
}
    ~CDROM(){cout<<"release a CDROM析构函数!\n";}

    //外部接口
    //获取两个私有成员,使外部可以访问私有成员
    CD_ROM_Install GetInstall()const{return install;}
    unsigned int GetCache_size()const{return cache_size;}
    CD_ROM_Interface GetInterface()const{return interf;}
    //设置私有成员:将外部传进来的参数赋值给私有数据成员
    void SetCD_ROM_Install(CD_ROM_Install ist){install = ist;}
    void SetCache_size(unsigned int s){cache_size = s;}
    void SetCD_ROM_Interface(CD_ROM_Interface itf){interf = itf;}

    void run(){cout<<"run the CDROM\n";}
    void stop(){cout<<"stop the CDROM\n";}
};
class Computer{
private:
    CPU my_cpu;
    RAM my_ram;
    CDROM my_cdrom;
    unsigned int storage_size;//GB存储容量
    unsigned int bandwidth;//MB带宽
public:
    //声明注意那个分号,在class外部进行具体的定义
    Computer(CPU c,RAM r,CDROM cd, unsigned int s,unsigned int b);
    ~Computer(){cout<<"computer 的析构函数\n";}

    void run(){
    //调用CPU,RAM,CDROM
        my_cpu.run();
        my_ram.run();
        my_cdrom.run();
        cout<<"Computer开始运行\n";
    }
    void stop(){
    //停止CPU,RAM,CDROM
        my_cpu.stop();
        my_ram.stop();
        my_cdrom.stop();
        cout<<"Computer停止运行\n";
    }
};
Computer::Computer(CPU c,RAM r,CDROM cd, unsigned int s,unsigned int b):my_cpu(c),my_ram(r),my_cdrom(cd) //组合类对象赋值格式如上。
{
    //简单数据成员赋值
    storage_size = s;
    bandwidth = b;
    cout<<"构造了一个Computer"< }

int main(int argc, _TCHAR* argv[])
{
    CPU a(p6,300,2.8);//声明类对象,并初始化
    a.run();
    a.stop();
    cout<<"*******************************"<     
    RAM b(DDR4, 1600, 8);//type,frequency,capacity
    b.run();
    b.stop();
    cout<<"*******************************"<

    CDROM c(external,1200 ,STAT);//install, cache_size, interface
    c.run();
    c.stop();
    cout<<"*******************************"<

    Computer com(a,b,c,8,120);
    com.run();
    com.stop();
    cout<<"*******************************"<

    return 0;//return之前会进行析构函数调用。
}

析构函数的调用

C++中,组合类,类的析构函数调用顺序_第1张图片

我们发现构造函数与析构函数数量不对等!如下解释

C++中,组合类,类的析构函数调用顺序_第2张图片

在第三部分首次出现的析构函数是对应的系统默认的拷贝构造函数

为了直观,在CPU中添加自定义的拷贝构造函数,位置,放于CPU析构函数之前,CPU构造函数之后。

//拷贝构造函数
    CPU(CPU &c){
        rank = c.rank;
        frequency = c.frequency;
        voltage = c.voltage;
        cout<<"拷贝构造了一个CPU!"<     }

computer是一个组合类,在定义构造函数时,Computer::Computer(CPU c,RAM r,CDROM cd, unsigned int s,unsigned int b):my_cpu(c),my_ram(r),my_cdrom(cd),需要调用两次拷贝构造函数分别用于形实结合和初始化列表,即形式结合拷贝构造函数和初始化列表的构造函数,两次调用后,在进行Computer构造函数的运行。

C++中,组合类,类的析构函数调用顺序_第3张图片

当Computer构造函数初始化结束后,对象的形参就会被因析构函数消失,自动的。我们不写自定义的析构函数,系统也有默认的析构函数对类的形参进行生命周期结束时的消除。这与普通类型的变量是一样的。

析构函数

当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:
一个对象以值传递的方式传入函数体 
一个对象以值传递的方式从函数返回 
一个对象需要通过另外一个对象进行初始化。

也就是说调用Computer构造函数时,需要拷贝cpu的对象a的所有参数给c

你可能感兴趣的:(C++)