欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

C++virtualdestructor-創(chuàng)新互聯(lián)

what happen when a derived class constructor is called?

我們先了解derived class在調(diào)用constructor的時(shí)候,首先先調(diào)用的是其父類的構(gòu)造函數(shù)
why?
首先我們的derived class obj中有所有的父類class的成員,在derived clas obj中其父類成員的可訪問程度根據(jù)父類成員所在位置所定(子類對(duì)象可以訪問父類的public和protected成員),所以在我們的子類構(gòu)造的時(shí)候要先構(gòu)造父類class(主要將其父類成員初始化)

賓縣ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!

沒有構(gòu)造函數(shù)編譯器會(huì)默認(rèn)分配一個(gè)編譯器給你,其功能僅僅是初始化成員而已

如下圖、

#includeclass Base{public:
    Base(){std::cout<< "constructor of Base "<<'\n'; }
};

class Derived: public Base{public:
    Derived(){std::cout<< "constructor of derived "<< '\n'; }
};

int main(){Derived* d1 = new Derived();
    return 0; 
}

打印如下

constructor of Base 
constructor of derived

當(dāng)然我們構(gòu)造子類的時(shí)候也可以選擇性的調(diào)用父類構(gòu)造函數(shù)

#includeclass Base{public:
    Base(){std::cout<< "constructor of Base "<<'\n'; }
    Base(int a) : Base_value(a) {std::cout<< "constructor of base and init base_value and base_value is "<< Base_value<< '\n';}
    int Base_value;
};

class Derived: public Base{public:
    Derived(): Base(){std::cout<< "constructor of derived "<< '\n'; }
    Derived(int a): Base(a){std::cout<< "call second constructor of Base_Value"<< '\n';}
};

int main(){Derived* d1 = new Derived(100);
   // Derived obj;
    return 0; 
}
Class繼承中的析構(gòu)函數(shù)

我們上面講到了子類中其實(shí)是有父類的成員,所以在構(gòu)造子類的時(shí)候先調(diào)用父類的構(gòu)造函數(shù)構(gòu)造父類,有構(gòu)造那么就有析構(gòu)函數(shù),析構(gòu)的順序正好相反,先析構(gòu)子類,再析構(gòu)父類如下

#includeclass Base{public:
    Base(){std::cout<< "constructor of Base "<<'\n'; }
    Base(int a) : Base_value(a) {std::cout<< "constructor of base and init base_value and base_value is "<< Base_value<< '\n';}
    ~Base(){std::cout<< "destructor of Base"<<'\n';}
    int Base_value;
};

class Derived: public Base{public:
    Derived(): Base(){std::cout<< "constructor of derived "<< '\n'; }
    Derived(int a): Base(a){std::cout<< "call second constructor of Base_Value"<< '\n';}
    ~Derived(){std::cout<< "destructor of Derived"<< '\n';}
};

int main(){Derived* d1 = new Derived(100);
   // Derived obj;
   std::cout<< "---------------"<< '\n';
   delete d1;
   return 0; 
}

打印如下

constructor of base and init base_value and base_value is 100
call second constructor of Base_Value
---------------
destructor of Derived
destructor of Base

我們?cè)倏聪旅娲a在deletederived class的時(shí)候只有base的destructor被執(zhí)行,而derived class的destructor并沒有被執(zhí)行

#includeclass Base{public:
    virtual void fun() {std::cout<< "base fun"<< std::endl; }
    ~Base() {std::cout<< "base destructor"<< std::endl;}
};

class Derive: public Base{public:
    virtual void fun() {std::cout<< "derived fun"<< '\n';}
    ~Derive() {std::cout<< "Derive destructor"<<'\n'; }
};

int main(){Base *b1 = new Base();
    Base *b2 = new Derive();

    b1->fun();
    b2->fun();

    delete b1;
    delete b2;

}

打印如下

base fun
derived fun
base destructor
base destructor

為什么會(huì)這樣?我們注意我們new完Derived class后將其賦值給Base class指針,此時(shí)我們new完Derived class生成的obj1雖然有derived class自有的成員變量,但是obj1歸根結(jié)底是Base class的obj,所以不可訪問Derived Class的額外成員這叫做object slicing
此時(shí)又有一個(gè)問題誕生,因?yàn)槲覀儗⒆宇惖膶?duì)象指針obj1賦值給父類,那么意味著obj1只能使用父類部分的成員,我們直接實(shí)例化父類這樣實(shí)例化后的對(duì)象又比obj1占用的空間小,又簡(jiǎn)單不是挺好嗎?為什么還要將子類對(duì)象obj1賦值給父類?這里有一個(gè)用處,就是父類中的一些成員是virtual,那么子類對(duì)象中父類vptr指向的函數(shù)為子類override后的地址,如下圖

class X {int     x;
    string str;

public:
    X() {}
    virtual ~X() {}

    virtual void printAll() {}
};

class Y : public X {int     y;

public:
    Y() {}
    ~Y() {}

    void printAll() {}
};

Y memory layout

  |                              |          
      |------------------------------|<------ Y class object memory layout
      |          int X::x            |
stack |------------------------------|
  |   |              int string::len |
  |   |string X::str ----------------|
  |   |            char* string::str |         
 \|/  |------------------------------|      |-------|--------------------------|
      |           X::_vptr           |------|       |       type_info Y        |
      |------------------------------|              |--------------------------|
      |          int Y::y            |              |    address of Y::~Y()    |
      |------------------------------|              |--------------------------|
      |               o              |              | address of Y::printAll() |
      |               o              |              |--------------------------|
      |               o              |              
------|------------------------------|--------
      |           X::X()             | 
      |------------------------------|       |   
      |           X::~X()            |       |
      |------------------------------|       | 
      |         X::printAll()        |      \|/ 
      |------------------------------|  text segment
      |           Y::Y()             |
      |------------------------------|
      |           Y::~Y()            |
      |------------------------------|
      |         Y::printAll()        |
      |------------------------------|
      |      string::string()        |
      |------------------------------|
      |      string::~string()       |
      |------------------------------|
      |      string::length()        |
      |------------------------------|
      |               o              |
      |               o              |
      |               o              |
      |                              |

上圖中Y繼承了X,那么Y對(duì)象中應(yīng)該含有X的vptr,上圖中Y的確含有X的vptr,但是X的vptr不再指向X的函數(shù)而是指向class Y override后的函數(shù)
所以我們?cè)谖鰳?gòu)函數(shù)中加上virtual關(guān)鍵字后子類對(duì)象memory layout中對(duì)應(yīng)的父類vptr指針(子類沒有定義virtual函數(shù),所以子類memory layout中沒有關(guān)于子類的vptr指針,如果子類對(duì)象obj1賦值給父類,那么obj1就會(huì)使用其內(nèi)存中x的vptr指向的虛函數(shù))指向的析構(gòu)函數(shù)變成了子類override的那一個(gè)(父類對(duì)象memory layout中vptr還是父類virtual function的地址),相反如果我們的子類中沒有對(duì)父類的虛函數(shù)重載定義,那么子類中的vptr指向的是父類函數(shù)的地址,然后編譯器執(zhí)行的時(shí)候會(huì)先在vptr中找對(duì)應(yīng)的函數(shù)地址,因?yàn)槲覀冏宇悰]有重新定義父類虛函數(shù),那么vptr中指向的還是父類對(duì)應(yīng)的虛函數(shù),則最后編譯器執(zhí)行的是父類的函數(shù)而不是子類的函數(shù).

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

當(dāng)前文章:C++virtualdestructor-創(chuàng)新互聯(lián)
文章源于:http://aaarwkj.com/article30/dohepo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、商城網(wǎng)站、企業(yè)網(wǎng)站制作、服務(wù)器托管、小程序開發(fā)、App設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名
日韩精品大全一区二区| 亚洲av在线av天堂| 日日激情综合久久一区| 福利视频免费观看欧美| 91出品国产福利在线| 色哟哟免费在线观看视频| 亚洲综合色日本日b网| 小明久久国内精品自线| 成人黄色片久久久大全| 中文字幕在线一区国产精品| 99久久偷拍美女大白屁股| 亚洲专区综合红桃av| 国内精品自拍亚洲视频| 日韩亚洲在线中文字幕| 亚洲av毛片在线免费| 亚洲日本一区二区高清在线| 免费看夫妻性生活视频| 哪里可以看日韩免费毛片| 亚洲午夜一区二区三区精品影院 | 国产片中文字幕在线观看| 婷婷激情综合亚洲五月色| 日韩欧美亚洲福利在线| 精品妇女一区二区三区| 欧美日韩国产在线91| 激情毛片av在线免费看| 日韩国产欧美亚洲一区不卡| 激情偷拍一区二区三区视频| 久久亚洲综合色一区二区三区| 成人精品播放视频在线观看| 天堂av在线观看播放| 日本精品在线亚洲国产欧美| 亚洲理论电影在线观看| 国产美女冒白浆视频免费| 日韩精品国产一区二区在线| 亚欧熟女乱色一二三区日韩| jvid视频在线观看免费| 国产一级黄色片免费看| 亚洲综合日韩精品国产av| 日韩欧美一区亚洲一区| 亚洲国产精品一区二区电影| 国产精品日本在线观看|