1. 程式人生 > >C++中,組合類,類的解構函式呼叫順序

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 <iostream>
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"<<endl;
}

int main(int argc, _TCHAR* argv[])
{
    CPU a(p6,300,2.8);//宣告類物件,並初始化
    a.run();
    a.stop();
    cout<<"*******************************"<<endl;
    
    RAM b(DDR4, 1600, 8);//type,frequency,capacity
    b.run();
    b.stop();
    cout<<"*******************************"<<endl;

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

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

    return 0;//return之前會進行解構函式呼叫。
}

解構函式的呼叫

我們發現建構函式與解構函式數量不對等!如下解釋

在第三部分首次出現的解構函式是對應的系統預設的拷貝建構函式

為了直觀,在CPU中新增自定義的拷貝建構函式,位置,放於CPU解構函式之前,CPU建構函式之後。

//拷貝建構函式
    CPU(CPU &c){
        rank = c.rank;
        frequency = c.frequency;
        voltage = c.voltage;
        cout<<"拷貝構造了一個CPU!"<<endl;
    }

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建構函式的執行。

當Computer建構函式初始化結束後,物件的形參就會被因解構函式消失,自動的。我們不寫自定義的解構函式,系統也有預設的解構函式對類的形參進行生命週期結束時的消除。這與普通型別的變數是一樣的。

解構函式

當類的物件需要拷貝時,拷貝建構函式將會被呼叫。以下情況都會呼叫拷貝建構函式:
一個物件以值傳遞的方式傳入函式體 
一個物件以值傳遞的方式從函式返回 
一個物件需要通過另外一個物件進行初始化。

也就是說呼叫Computer建構函式時,需要拷貝cpu的物件a的所有引數給c