国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

面向?qū)ο蟪绦蛟O(shè)計(jì)之訪問(wèn)控制、繼承與拷貝控制

2019-11-10 22:50:51
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

訪問(wèn)控制與繼承: 一個(gè)類使用PRotected關(guān)鍵字來(lái)聲明那些希望與派生類分享但是不想被其他公共訪問(wèn)的成員。其性質(zhì)如下: (1)和私有成員類似,受保護(hù)的成員對(duì)類的用戶是不可訪問(wèn)的 (2)和公有成員類似,受保護(hù)的成員對(duì)于派生類的成員和友元來(lái)時(shí)是可訪問(wèn)的。 (3)派生類的成員或友元只能通過(guò)派生類對(duì)象來(lái)訪問(wèn) 基類的受保護(hù)成員。派生類對(duì)于一個(gè)基類對(duì)象中的受保護(hù)成員沒(méi)有任何訪問(wèn)特權(quán)。

這里寫圖片描述


某個(gè)類對(duì)其繼承而來(lái)的成員的訪問(wèn)權(quán)限受兩個(gè)因素的影響: (1)基類中該成員的訪問(wèn)說(shuō)明符 (2)派生類的派生列表中的訪問(wèn)說(shuō)明符

這里寫圖片描述 對(duì)基類成員的訪問(wèn)權(quán)限只與基類中的訪問(wèn)說(shuō)明符有關(guān)。派生訪問(wèn)說(shuō)明符的目的是控制派生類用戶(包括派生類的派生類在內(nèi))對(duì)于基類成員的訪問(wèn)權(quán)限。

這里寫圖片描述

派生訪問(wèn)說(shuō)明符還可以繼承自派生類的新類的訪問(wèn)權(quán)限。

這里寫圖片描述


派生類向基類轉(zhuǎn)換的可訪問(wèn)性: 對(duì)于代碼中的某個(gè)給定節(jié)點(diǎn)來(lái)說(shuō),如果基類的共有成員是可訪問(wèn)的,則派生類向基類的類型轉(zhuǎn)換也是可訪問(wèn)的。反之,則不行。 這里寫圖片描述 這里寫圖片描述

//用戶代碼可以使用派生類向基類轉(zhuǎn)換如果派生類繼承基類的方式是公有的,其他方式則不行//考慮類base和它的派生類已知Base *p=&d1;//d1的類型是Pub_Derv,正確p=&d2;//d2的類型是Priv_Derv,錯(cuò)誤p=&d3;//d3的類型是Prot_Derv,錯(cuò)誤p=&dd1;//dd1的類型是Derived_from_public,正確p=&dd2;//dd2的類型是Derived_from_private,錯(cuò)誤p=&dd3;//dd3的類型是Derived_from_protected,錯(cuò)誤

友元關(guān)系不具有繼承性,每個(gè)類負(fù)責(zé)控制各自成員的訪問(wèn)權(quán)限。

這里寫圖片描述


當(dāng)我們需要改變派生類繼承的某個(gè)名字的訪問(wèn)級(jí)別,可以通過(guò)使用using聲明。

class Base{public: std::size_t size() const{return n;}protected: std::size_t n;};class Derived:private Base //Base的成員在Derived是私有的。{public: using Base::size;protected: using Base::n;//改變?cè)L問(wèn)權(quán)限};

默認(rèn)的繼承保護(hù)級(jí)別:

這里寫圖片描述


繼承中的類作用域:

當(dāng)存在繼承關(guān)系時(shí),派生類的作用域嵌套在其基類的作用域之內(nèi)。如果一個(gè)名字在派生類的作用域內(nèi)無(wú)法正確解析,則編譯器將繼續(xù)在外層的基類作用域?qū)ふ以撁值亩x。


派生類的成員將隱藏同名的基類成員。

這里寫圖片描述

我們可以通過(guò)作用域運(yùn)算符來(lái)使用隱藏的成員。除了覆蓋繼承而來(lái)的虛函數(shù)之外,派生類最好不要重用其他定義在基類的名字。

這里寫圖片描述


如果派生類(內(nèi)層作用域)的成員與基類(外層作用域)的某個(gè)成員同名,則派生類將在其作用域隱藏該基類成員,即使派生類成員和基類成員的形參列表不一致。

這里寫圖片描述


通過(guò)基類調(diào)用隱藏的虛函數(shù),調(diào)用的時(shí)候主要是看是什么類的指針,是否有虛函數(shù)覆蓋。

#include <iostream>class Base{public: Base(int v):v(v){} virtual int fcn() { return v; } int v=0;};class D1:public Base{public: D1(int d1):Base(d1){} int fcn(int d1) { return d1+1; } virtual void f2(){std::cout<<"f2() in D1"<<std::endl;}};class D2:public D1{public: D2(int dd):D1(dd){} int fcn(int d2) { return d2; } int fcn() { return v+100; } void f2(){std::cout<<"f2() in D2"<<std::endl;}};int main(){ Base b(10); D1 d1(10); D2 d2(10); Base *bp1=&b,*bp2=&d1,*bp3=&d2; std::cout<<bp1->fcn()<<std::endl;//10,虛調(diào)用,Base::fcn() std::cout<<bp2->fcn()<<std::endl;//10,虛調(diào)用,Base::fcn() std::cout<<bp3->fcn()<<std::endl;//110,調(diào)用D2::fcn() D1 *d1p=&d1; D2 *d2p=&d2;// bp2->f2();//錯(cuò)誤,base沒(méi)有f2的成員 d1p->f2();//D1::f2() d2p->f2();//D2::f2() Base *p1=&d2; D1 *p2=&d2; D2 *p3=&d2; //p1->fcn(42);//錯(cuò)誤,Base沒(méi)有fcn(int) std::cout<< p2->fcn(42)<<std::endl;//43,D1::fcn(42) std::cout<< p3->fcn(42)<<std::endl;//42,D2::fcn(42) return 0; }

虛折構(gòu)函數(shù): 繼承關(guān)系對(duì)基類拷貝控制最直接的影響是基類通常應(yīng)該定義一個(gè)虛折構(gòu)函數(shù),這樣我們就能動(dòng)態(tài)分配繼承體系中的對(duì)象了。如果基類的折構(gòu)函數(shù)不是虛函數(shù),則delete一個(gè)指向派生類對(duì)象的基類指針將產(chǎn)生未定義的行為。

Quote *itemp=new Quote;delete itemp;//調(diào)用Quote的折構(gòu)函數(shù)itemp=new Bulk_quote;delete itemp;//調(diào)用Bulk_quote的折構(gòu)函數(shù)

基類或派生類的合成拷貝控制成員的行為與其他合成的構(gòu)造函數(shù)、賦值運(yùn)算符或折構(gòu)函數(shù)類似,即它們對(duì)類本身的成員依次進(jìn)行初始化,賦值或銷毀操作。此外,這些合成的成員還負(fù)責(zé)使用直接基類中對(duì)應(yīng)的操作對(duì)一個(gè)對(duì)象的直接基類進(jìn)行初始化、賦值或銷毀操作(從上到下)。

對(duì)于派生類的折構(gòu)函數(shù)來(lái)說(shuō),它除了銷毀派生類自己的成員外,還負(fù)責(zé)銷毀派生類的直接基類,該直接基類又銷毀它自己的直接基類,以此類推直至繼承鏈的頂端。(自下而上)。

某些定義基類的方式可能導(dǎo)致有的派生類成員成為被刪除的函數(shù)

這里寫圖片描述

class B{public: B(); B(const B&)=delete; //其他成員,不含移動(dòng)構(gòu)造函數(shù)};class D:public B{ //沒(méi)有聲明任何構(gòu)造函數(shù)};D d;//正確。D的合成默認(rèn)構(gòu)造函數(shù)使用B的默認(rèn)構(gòu)造函數(shù)D d2(d);//錯(cuò)誤,D的合成拷貝構(gòu)造函數(shù)是刪除的。D d3(std::move(d));//錯(cuò)誤,隱式使用D的被刪除的拷貝構(gòu)造函數(shù)//因?yàn)镼uote定義了折構(gòu)函數(shù)而不能擁有合成的移動(dòng)操作,因此當(dāng)我們移動(dòng)Quote對(duì)象時(shí)實(shí)際使用的是合成的拷貝操作。

因?yàn)榛惾鄙僖苿?dòng)操作會(huì)阻止派生類擁有自己的合成移動(dòng)操作,所以當(dāng)我們卻是需要執(zhí)行移動(dòng)操作時(shí)應(yīng)該首先在基類進(jìn)行定義。但必須顯式的定義這些成員。

這里寫圖片描述


當(dāng)派生類定義拷貝或移動(dòng)操作時(shí),該操作負(fù)責(zé)拷貝或移動(dòng)包括基類部分成員在內(nèi)的整個(gè)對(duì)象。 在默認(rèn)情況下,基類默認(rèn)構(gòu)造函數(shù)初始化派生類對(duì)象的基類部分。如果我們想拷貝或移動(dòng)基類部分,則必須在派生類的構(gòu)造函數(shù)初始值列表中顯式地使用基類的拷貝或移動(dòng)構(gòu)造函數(shù)。

class B {/*......*/};class D:public Base{public: //Base(d)會(huì)匹配Base的拷貝構(gòu)造函數(shù)。D類型的對(duì)象d被綁定到該構(gòu)造函數(shù)的Base&形參上。Base的拷貝構(gòu)造函數(shù)負(fù)責(zé)將d的基類部分拷貝給要?jiǎng)?chuàng)建的對(duì)象。 D (const D& d):Base(d)//拷貝基類成員 /* D的成員的初始值 */{......} D (D&& d):Base(std::move(d))//移動(dòng)基類成員 /* D的成員的初始值 */{......}};

派生類的賦值運(yùn)算符也必須顯式地為其基類部分賦值。

D D&::Operator=(const D &rhs){ Base::operator=(rhs);//為基類部分賦值 ..... return *this}

派生類折構(gòu)函數(shù)只負(fù)責(zé)銷毀由派生類自己分配的資源。

class D:public Base{public: //Base::~Base自動(dòng)執(zhí)行 ~D(){//用戶定義};};

我們可以使用基類名的using聲明語(yǔ)句來(lái)說(shuō)明派生類繼承基類構(gòu)造函數(shù)。但是一個(gè)構(gòu)造函數(shù)的using聲明不會(huì)改變?cè)摌?gòu)造函數(shù)的訪問(wèn)級(jí)別。而且,一個(gè)using聲明的語(yǔ)句不能指定explicit或constexpr.

class B:public A{public: using A::A;//繼承基類A的構(gòu)造函數(shù)};

當(dāng)一個(gè)基類構(gòu)造函數(shù)含有默認(rèn)實(shí)參,這些實(shí)參并不會(huì)被繼承。相反,派生類將獲得多個(gè)繼承的構(gòu)造函數(shù),其中每個(gè)構(gòu)造函數(shù)分別省略掉一個(gè)含有默認(rèn)實(shí)參的形參。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 宜章县| 邵东县| 柘荣县| 杂多县| 汶上县| 古蔺县| 原平市| 新竹县| 汪清县| 襄樊市| 嘉祥县| 昌黎县| 唐河县| 德化县| 海宁市| 阜城县| 红桥区| 葵青区| 丹东市| 晋江市| 青川县| 怀化市| 南昌市| 吴桥县| 伊宁县| 卓尼县| 慈利县| 奉新县| 剑阁县| 盐城市| 井冈山市| 凉城县| 武山县| 武川县| 旬邑县| 阜城县| 南汇区| 阜阳市| 新巴尔虎右旗| 枣阳市| 海城市|