中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

使用dw做門戶網(wǎng)站營銷軟文寫作

使用dw做門戶網(wǎng)站,營銷軟文寫作,營銷企業(yè)網(wǎng)站建設(shè)應(yīng)遵守的原則,全球速賣通入駐條件C多態(tài)概念詳解 一,多態(tài)概念二,多態(tài)的定義2.1 多態(tài)構(gòu)成的條件2.2 什么是虛函數(shù)2.3 虛函數(shù)的重寫2.3.1 虛函數(shù)重寫的特例2.3.2 override和final 2.4 重載和重寫(覆蓋)和重定義(隱藏)的區(qū)別 三,抽象…

C++多態(tài)概念詳解

  • 一,多態(tài)概念
  • 二,多態(tài)的定義
    • 2.1 多態(tài)構(gòu)成的條件
    • 2.2 什么是虛函數(shù)
    • 2.3 虛函數(shù)的重寫
      • 2.3.1 虛函數(shù)重寫的特例
      • 2.3.2 override和final
    • 2.4 重載和重寫(覆蓋)和重定義(隱藏)的區(qū)別
  • 三,抽象類
    • 3.1 概念
    • 3.2 接口繼承和實(shí)現(xiàn)繼承
  • 四,多態(tài)的原理
    • 4.1 虛函數(shù)表
    • 4.2 多態(tài)調(diào)用的底層原理
    • 4.3 靜態(tài)綁定和動態(tài)綁定
  • 五,單繼承和多繼承的虛函數(shù)表
    • 5.1 單繼承的虛函數(shù)表
    • 5.2 多繼承的虛函數(shù)表
  • 六,繼承和多態(tài)的常見問題

一,多態(tài)概念

上節(jié)我們看了繼承,現(xiàn)在我們來看多態(tài)。

那么什么是多態(tài)呢?通俗來說,就是多種形態(tài),具體點(diǎn)就是去完成某個(gè)行為,當(dāng)不同的對象去完成時(shí)會產(chǎn)生出不同的狀態(tài)。
舉個(gè)例子,對于買票這件事,一個(gè)成人去買的話是全票,但如果是學(xué)生則半價(jià),在這件事中成人和學(xué)生都可以買票,但是不同的人買,票價(jià)卻不同,這就是一種多態(tài)行為。

二,多態(tài)的定義

2.1 多態(tài)構(gòu)成的條件

多態(tài)是在不同繼承關(guān)系的類對象,去調(diào)用同一函數(shù),產(chǎn)生了不同的行為。

在繼承中構(gòu)成多態(tài)要滿足兩個(gè)條件:

  1. 在子類中對父類的虛函數(shù)進(jìn)行重寫,且必須調(diào)用。
  2. 通過父類的指針或者引用調(diào)用虛函數(shù)

那什么是虛函數(shù)及什么是重寫,我們下面就來講解

2.2 什么是虛函數(shù)

其實(shí)虛函數(shù)就是加上virtual的函數(shù), 比如下面的代碼:

class Person {
public:virtual void BuyTicket(){cout << "買票-全價(jià)" << endl;}
};

2.3 虛函數(shù)的重寫

虛函數(shù)要完成重寫,那么重寫就是子類中有一個(gè)和父類一樣的虛函數(shù),這個(gè)虛函數(shù)要求:

函數(shù)名,返回值類型,參數(shù)列表相同

class Person {
public:virtual void BuyTicket() {cout << "買票-全價(jià)" << endl; }
};
class Student : public Person {
public:virtual void BuyTicket() {cout << "買票-半價(jià)" << endl; }
};

2.3.1 虛函數(shù)重寫的特例

虛函數(shù)的重寫有兩個(gè)特例:

  1. 協(xié)變----->重寫的虛函數(shù)的類型可以不一樣,但是要是父子類關(guān)系的指針或者引用
class A{};
class B : public A {};
class Person {
public:virtual A* f() {return new A;}
};
class Student : public Person {
public:virtual B* f() {return new B;}
};

B這個(gè)類是A類的子類,Student類是Person的子類,且都有虛函數(shù)f(),但是這兩個(gè)虛函數(shù)的類型分別是A,B父子類的指針,這就是協(xié)變。


  1. 析構(gòu)函數(shù)的重寫 ----->父子類的析構(gòu)函數(shù)會被統(tǒng)一成destuctor,如果不加virtual構(gòu)成重寫,則會構(gòu)成隱藏,不會調(diào)用到父類的析構(gòu)函數(shù),進(jìn)而造成內(nèi)存泄漏(子類的資源沒有釋放完)
class Person {
public:virtual ~Person() {cout << "~Person()" << endl;}
};
class Student : public Person {
public:virtual ~Student() {cout << "~Student()" << endl;}
};
// 只有派生類Student的析構(gòu)函數(shù)重寫了Person的析構(gòu)函數(shù),下面的delete對象調(diào)用析構(gòu)函
//數(shù),才能構(gòu)成多態(tài),才能保證p1和p2指向的對象正確的調(diào)用析構(gòu)函數(shù)。
int main()
{Person* p1 = new Person;Person* p2 = new Student;delete p1;delete p2;return 0;
}

  1. 虛函數(shù)重寫時(shí),父類加了virtual,而子類不加virtual也構(gòu)成重寫(建議加上)
class Person {
public:virtual void BuyTicket() {cout << "買票-全價(jià)" << endl; }
};
class Student : public Person {
public:void BuyTicket() {cout << "買票-半價(jià)" << endl; }
};

2.3.2 override和final

C++中對于重寫的要求比較嚴(yán)格,所以有了這兩個(gè)關(guān)鍵字來檢測是否重寫


現(xiàn)在有這樣一個(gè)問題:如何實(shí)現(xiàn)一個(gè)類,讓其不能被繼承
有兩種辦法:

  1. 讓父類的構(gòu)造函數(shù)私有,以為子類的構(gòu)造要用到父類的構(gòu)造,但是這樣會讓子類不能實(shí)例化出對象
  2. final修飾為最終類

final也可以修飾虛函數(shù),修飾后不能被重寫!


override加在派生類后面檢查是否完成重寫

2.4 重載和重寫(覆蓋)和重定義(隱藏)的區(qū)別

重載我們在前面學(xué)過,重寫在原理層面也叫覆蓋,上一節(jié)講的隱藏也叫重定義。

看下面的圖我們可以看到三者的區(qū)別:
在這里插入圖片描述
其實(shí)更深層次來看重寫就是一種特殊的重定義!

三,抽象類

3.1 概念

我們先來看什么是純虛函數(shù),就是在虛函數(shù)后面加上 = 0 ,

virtual void fun () = 0

包含純虛函數(shù)的類叫抽象類(接口類),并且抽象類不能實(shí)例化對象。

抽象類就像某類事物抽象出來的一個(gè)特征,不是一個(gè)具體的東西。例如車是一個(gè)抽象類,但是像寶馬,奧迪,奔馳是車這個(gè)抽象類繼承的具體的可實(shí)例化的類。

抽象類的派生類必須重寫虛函數(shù),否則不能實(shí)例化,因?yàn)椴恢貙懽宇惾匀粫r(shí)抽象類,(間接強(qiáng)制子類重寫虛函數(shù))

3.2 接口繼承和實(shí)現(xiàn)繼承

普通函數(shù)的繼承是一種實(shí)現(xiàn)繼承,派生類繼承基類函數(shù),繼承了實(shí)現(xiàn)為了復(fù)用

虛函數(shù)的繼承是一種接口繼承繼承了父類的接口為了重寫實(shí)現(xiàn),達(dá)成多態(tài)。

四,多態(tài)的原理

普通函數(shù)和虛函數(shù)都是存在代碼段的,談到多態(tài)的原理我們就不得不說下類對象的存儲設(shè)計(jì)
如下圖:在這里插入圖片描述
一個(gè)類中存放著一個(gè)指向類成員函數(shù)表的指針,而這個(gè)表中存放的是函數(shù)的地址,多態(tài)的原理就和這種存儲結(jié)構(gòu)息息相關(guān)。

4.1 虛函數(shù)表

先來試想一下如何計(jì)算一個(gè)有虛函數(shù)的類的大小:

class Base
{
public:virtual void Func1(){cout << "Func1()" << endl;}
private:int _b = 1;
};
int main() {Base b;cout << sizeof(b) << endl;return 0;
}

運(yùn)行后我們可以發(fā)現(xiàn)
在這里插入圖片描述
這是為什么呢?

這是因?yàn)锽ase這個(gè)類中除了_b這個(gè)成員外,還有一個(gè)指針_vfptr,這個(gè)指針是虛函數(shù)表指針(虛表指針),指向的是虛函數(shù)指針數(shù)組。
在這里插入圖片描述
那么這個(gè)指針指向的表是干嘛的呢,我們繼續(xù)來分析,我們讓派生類Derive去繼承Base類,并且增加虛函數(shù)。

class Base
{
public:virtual void Func1(){cout << "Base::Func1()" << endl;}virtual void Func2(){cout << "Base::Func2()" << endl;}void Func3(){cout << "Base::Func3()" << endl;}
private:int _b = 1;
};class Derive : public Base
{
public:virtual void Func1(){cout << "Derive::Func1()" << endl;}
private:int _d = 2;
};
int main()
{Base b;Derive d;return 0;
}

經(jīng)過調(diào)試我們可以看到
在這里插入圖片描述

在Base和Derive類中都有_vfptr指針,指向了一張表,里面貌似存放了虛函數(shù)。而且Derive的這個(gè)表里第一個(gè)存放的是重寫的虛函數(shù),第二個(gè)存放的是Base的第二個(gè)虛函數(shù)。

其實(shí)這個(gè)表是虛函數(shù)表(virtual function table),虛表中存儲的是虛函數(shù)的地址(指針)。
派生類的虛函數(shù)表繼承自父類的虛函數(shù)表,但是會用其自己的虛函數(shù)覆蓋虛表中第一個(gè)位置(所以虛函數(shù)的重寫也叫覆蓋)

重寫時(shí)語法層面的,覆蓋是原理層面的

在這里插入圖片描述
虛表以空結(jié)尾,并且虛函數(shù)存放的順序和聲明的順序一致

派生類有兩部分,一部分是父類的,一部分是自己的,派生類沒有自己單獨(dú)的虛表,而是繼承的父類的,拷貝父類的虛函數(shù)表,并覆蓋自己重寫的虛函數(shù)


知道了虛表的存在后,我們繼續(xù)探索。

如果派生類有一個(gè)自己的虛函數(shù)呢 ? 會在虛表里怎么存放

虛函數(shù)表是存放在常量區(qū)的,在編譯時(shí)生成好的,虛表指針的初始化是在構(gòu)造函數(shù)初始化列表最前面(所有對象初始化之前)。

同類型的對象共享一個(gè)虛函數(shù)表

在這里插入圖片描述

4.2 多態(tài)調(diào)用的底層原理

如何做到指向父類調(diào)用父類虛函數(shù),指向子類調(diào)子類呢?

class Person {
public:virtual void BuyTicket() { cout << "買票-全價(jià)" << endl; }
};
class Student : public Person {
public:virtual void BuyTicket() { cout << "買票-半價(jià)" << endl; }
};
void Func(Person& p)
{p.BuyTicket();
}
int main()
{Person Mike;Func(Mike);Student Johnson;Func(Johnson);return 0;
}

運(yùn)行后可以看到:

在這里插入圖片描述
在這里插入圖片描述
由上面的圖可知,指向父類時(shí),會在父類的虛函數(shù)表中查找對應(yīng)的虛函數(shù)。 指向子類時(shí),會在切割后的父類(子類中完成對父類虛函數(shù)重寫)的虛函數(shù)表中查找已經(jīng)被覆蓋的對應(yīng)的子類的虛函數(shù)


總結(jié)一下就是,多態(tài)調(diào)用就是在運(yùn)行時(shí)去虛函數(shù)表中找虛函數(shù)的地址來進(jìn)行調(diào)用,所以可以達(dá)到指向父類調(diào)父類,指向子類調(diào)子類虛函數(shù)。

如果去掉 virtual ,則是普通調(diào)用,在編譯時(shí)通過調(diào)用者的類型確定函數(shù)的地址

4.3 靜態(tài)綁定和動態(tài)綁定

簡單來說,靜態(tài)就是編譯時(shí),動態(tài)就是運(yùn)行時(shí),

靜態(tài)綁定是在編譯時(shí)確定程序的行為,也叫靜態(tài)多態(tài)(函數(shù)重載),
動態(tài)綁定是在程序運(yùn)行期間確定程序行為

五,單繼承和多繼承的虛函數(shù)表

在單繼承和多繼承關(guān)系中,我們關(guān)注的是派生類對象的虛表模型,因?yàn)榛惖奶摫砟P颓懊嫖覀円呀?jīng)看過了,沒什么需要特別研究的。

5.1 單繼承的虛函數(shù)表

看下面的代碼:

class Base {
public:virtual void func1() { cout << "Base::func1" << endl; }virtual void func2() { cout << "Base::func2" << endl; }
private:int a;
};
class Derive :public Base {
public:virtual void func1() { cout << "Derive::func1" << endl; }virtual void func3() { cout << "Derive::func3" << endl; }virtual void func4() { cout << "Derive::func4" << endl; }
private:int b;
};

在這里插入圖片描述
單繼承就是將基類的虛函數(shù)表拷貝下來,將自己重寫的虛函數(shù)覆蓋。

5.2 多繼承的虛函數(shù)表

假設(shè)一個(gè)派生類繼承了兩個(gè)基類,計(jì)算這個(gè)派生類的大小

看下面的代碼:

class Base1 {
public:virtual void func1() { cout << "Base1::func1" << endl; }virtual void func2() { cout << "Base1::func2" << endl; }
private:int b1;
};
class Base2 {
public:virtual void func1() { cout << "Base2::func1" << endl; }virtual void func2() { cout << "Base2::func2" << endl; }
private:int b2;
};
class Derive : public Base1, public Base2 {
public:virtual void func1() { cout << "Derive::func1" << endl; }virtual void func3() { cout << "Derive::func3" << endl; }
private:int d1;
};int main() {Derive d;return 0;
}

在這里插入圖片描述

派生類繼承了兩個(gè)基類的虛表,所以說有兩張?zhí)摫?#xff0c;并且同時(shí)覆蓋了重寫的虛函數(shù)地址,如果派生類有自己的虛函數(shù),那么這個(gè)虛函數(shù)的地址放在繼承的第一張?zhí)摫碇小?/code>

六,繼承和多態(tài)的常見問題

  1. 內(nèi)聯(lián)函數(shù)也可以是虛函數(shù),當(dāng)內(nèi)聯(lián)函數(shù)是普通調(diào)用時(shí),其內(nèi)聯(lián)屬性還在,當(dāng)多態(tài)調(diào)用時(shí),會失去其內(nèi)聯(lián)屬性。
  2. 靜態(tài)成員函數(shù)不能是虛函數(shù),因?yàn)闆]有this指針,無法訪問虛函數(shù)表。
  3. 構(gòu)造函數(shù)不能是虛函數(shù),因?yàn)樘摫碇羔樖窃跇?gòu)造函數(shù)初始化列表之前初始化的
http://www.risenshineclean.com/news/26917.html

相關(guān)文章:

  • 專業(yè)建站公司服務(wù)百度手機(jī)網(wǎng)頁版
  • 黑龍江省網(wǎng)站建設(shè)北京seo顧問
  • 陽江網(wǎng)站建設(shè)公司百度網(wǎng)站官網(wǎng)入口
  • 網(wǎng)站的數(shù)據(jù)庫怎么備份網(wǎng)絡(luò)營銷與網(wǎng)站推廣的
  • 青島做外貿(mào)網(wǎng)站廣州疫情最新消息
  • 濟(jì)寧網(wǎng)站建設(shè) 田振在線磁力搜索引擎
  • c 做的網(wǎng)站又哪些廈門關(guān)鍵詞優(yōu)化網(wǎng)站
  • 林州網(wǎng)站建設(shè)外貿(mào)網(wǎng)站平臺
  • java web網(wǎng)站開發(fā)流程廈門人才網(wǎng)最新招聘信息網(wǎng)
  • 北京制作頁面網(wǎng)站搜索優(yōu)化官網(wǎng)
  • 微信朋友圈廣告投放平臺杭州上城區(qū)抖音seo有多好
  • 找美工做網(wǎng)站多少錢長沙seo優(yōu)化推廣公司
  • 洛陽做網(wǎng)站哪家便宜沈陽seo排名收費(fèi)
  • 靜態(tài)網(wǎng)站制作模板百度seo關(guān)鍵詞排名優(yōu)化
  • 創(chuàng)業(yè)商機(jī)網(wǎng)餐飲seoapp推廣
  • dz論壇怎么做視頻網(wǎng)站上海十大營銷策劃公司
  • 日照網(wǎng)站建設(shè)哪家好看廣告賺錢的平臺
  • 怎么用css做網(wǎng)站背景圖整站優(yōu)化seo公司哪家好
  • 大連網(wǎng)站建設(shè)特色南京seo關(guān)鍵詞排名
  • asp動態(tài)網(wǎng)站建設(shè)模擬搜索點(diǎn)擊軟件
  • 源碼下載網(wǎng)站源碼廣西網(wǎng)絡(luò)優(yōu)化seo
  • 網(wǎng)站下載的軟件怎么安裝代寫1000字多少錢
  • 集團(tuán)網(wǎng)站建設(shè)要多少錢sem推廣軟件選哪家
  • 一級a做爰片免費(fèi)觀網(wǎng)站看無碼滄州網(wǎng)站建設(shè)
  • 網(wǎng)站建設(shè)英語翻譯資料產(chǎn)品軟文范例軟文
  • 深圳做網(wǎng)站 漢獅網(wǎng)絡(luò)seo合作代理
  • 長沙網(wǎng)站策劃在線優(yōu)化網(wǎng)站
  • 鄂州市政府網(wǎng)長沙seo培訓(xùn)
  • 青島學(xué)網(wǎng)站建設(shè)的大學(xué)搜索關(guān)鍵詞技巧
  • 做網(wǎng)站需要公司么中國制造網(wǎng)網(wǎng)站類型