摘要:基類中的構(gòu)造函數(shù)和析構(gòu)函數(shù)不能被繼承,在派生類中需要定義新的構(gòu)造函數(shù)和析構(gòu)函數(shù),私有成員不能被繼承。對象訪問在派生類外部,通過派生類的對象對從基類繼承來的成員的訪問。
1、類與類之間的關(guān)系有哪些?
與類之間的關(guān)系分為縱向和橫向兩種:
縱向就是繼承;橫向包括:依賴、關(guān)聯(lián)、聚合和組合。(這里不進(jìn)行解釋,詳解鏈接:https://blog.csdn.net/u014694510/article/details/88316605.
2、什么是繼承?繼承有什么作用?
所謂繼承就是從先輩出得到屬性和行為特征。類的繼承就是新的類從已有類那里得到已有的特征;從另一個(gè)角度來看,類的繼承和派生機(jī)制使程序員無需修改已有類,只需在此類的基礎(chǔ)上,通過少量代碼或修改少量代碼的方法得到新的類,從而很好的解決了代碼重用的問題。由已有類產(chǎn)生新類時(shí),新類便包含了已有類的特征,同時(shí)也可以加入自己的新特征。已有類被稱為基類或者父類,產(chǎn)生的新類被稱為派生類或者子類。
3、繼承有哪些分類?
派生類的繼承方式有私有繼承(private),公有繼承(public),保護(hù)繼承(protect)
4、基類成員在派生類的訪問屬性是怎樣的?
基類中的成員 | 在公有派生類的訪問屬性 | 在私有派生類中的訪問屬性 | 在保護(hù)派生類中的訪問屬性 |
---|---|---|---|
私有成員 | 不可直接訪問 | 不可直接訪問 | 不可直接訪問 |
公有成員 | 公有 | 私有 | 保護(hù) |
保護(hù)成員 | 保護(hù) | 私有 | 保護(hù) |
5、基類的成員函數(shù)都能被繼承嗎?
不是。基類中的構(gòu)造函數(shù)和析構(gòu)函數(shù)不能被繼承,在派生類中需要定義新的構(gòu)造函數(shù)和析構(gòu)函數(shù),私有成員不能被繼承。
6、派生類對基類成員的訪問規(guī)則是怎樣的?
內(nèi)部訪問:由派生類中新增的成員函數(shù)對基類繼承來的成員的訪問。
對象訪問:在派生類外部,通過派生類的對象對從基類繼承來的成員的訪問。
私有繼承的訪問規(guī)則:
基類中的成員 | 私有成員 | 公有成員 | 保護(hù)成員 |
---|---|---|---|
內(nèi)部訪問 | 不可訪問 | 可訪問 | 可訪問 |
對象訪問 | 不可訪問 | 不可訪問 | 不可訪問 |
公有繼承的訪問規(guī)則:
基類中的成員 | 私有成員 | 公有成員 | 保護(hù)成員 |
---|---|---|---|
內(nèi)部訪問 | 不可訪問 | 可訪問 | 可訪問 |
對象訪問 | 不可訪問 | 可訪問 | 不可訪問 |
保護(hù)成員的訪問規(guī)則:
基類中的成員 | 私有成員 | 公有成員 | 保護(hù)成員 |
---|---|---|---|
內(nèi)部訪問 | 不可訪問 | 可訪問 | 可訪問 |
對象訪問 | 不可訪問 | 不可訪問 | 不可訪問 |
先看個(gè)簡單的代碼了解一下:
class Person{public: void work() { cout << "work()" << endl; } void eat() { cout << "eat()" << endl; }protected:private: string _name; int _age; string _sex;};class Student :public Person{public: void show() { cout << _name << endl; cout << _age << endl; cout << _sex << endl; }};
這里會(huì)報(bào)錯(cuò):
但如果把這些私有屬性改為保護(hù)或者公有的話就不會(huì)報(bào)錯(cuò):
class Person{public: void work() { cout << "work()" << endl; } void eat() { cout << "eat()" << endl; }protected: string _name; int _age; string _sex;private:};class Student :public Person{public: void show() { cout << _name << endl; cout << _age << endl; cout << _sex << endl; }};
這就是因?yàn)樗接谐蓡T不可以被繼承。
總結(jié):子類繼承的父類成員,在自身中的權(quán)限不能高于繼承權(quán)限()
再看這個(gè)代碼:
class Person{public: Person(string name,int age,string sex,string wife=string()) { _name=name; _age=age; _sex=sex; _wife=wife; } ~Person() { cout<<"~Person()"<<endl; } void work() { cout << "work()" << endl; } void eat() { cout << "eat()" << endl; }protected: string _name; int _age; string _sex;private: string wife;};class Student :public Person{public: void show() { cout << _name << endl; cout << _age << endl; cout << _sex << endl; }};int main(){ Student s;//報(bào)錯(cuò),無法引用默認(rèn)的構(gòu)造函數(shù) s.show();}
這樣改正之后錯(cuò)誤消失(給派生類定義構(gòu)造函數(shù)):
class Student :public Person{public: Student(string name, int age, string sex, string num, string wife = string()) :Person(name,age,sex,wife) { cout << "Student(string name, int age, string sex, string num, string wife = string())" << endl; _num = num; } void show() { cout << _name << endl; cout << _age << endl; cout << _sex << endl; cout << _num << endl; }private: string _num;};int main(){ Student s("zjh",11,"man","1111"); s.show();}
錯(cuò)誤原因:C++規(guī)定,當(dāng)基類的構(gòu)造函數(shù)沒有參數(shù),或沒有顯示定義構(gòu)造函數(shù)時(shí),派生類可以不向基類傳遞參數(shù),甚至可以不定義構(gòu)造函數(shù)。當(dāng)基類含有帶參數(shù)的構(gòu)造函數(shù)時(shí),派生類必須定義構(gòu)造函數(shù),以提供把參數(shù)傳遞給構(gòu)造函數(shù)的途徑。
7、派生類構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行順序是怎樣的?
通常情況下,當(dāng)創(chuàng)建派生類對象時(shí),首先執(zhí)行基類的構(gòu)造函數(shù),隨后再執(zhí)行派生類的構(gòu)造函數(shù);當(dāng)撤銷派生類對象時(shí),則先執(zhí)行派生類的析構(gòu)函數(shù),隨后再執(zhí)行基類的析構(gòu)函數(shù)。
8、派生類構(gòu)造函數(shù)的參數(shù)列表是怎樣構(gòu)成的?
Student(string name, int age, string sex, string num, string wife = string()) :Person(name,age,sex,wife)
從上面列出的派生類Student
構(gòu)造函數(shù)首行中可以看到,派生類構(gòu)造函數(shù)名后邊括號內(nèi)的總參數(shù)表中包括了參數(shù)的類型和參數(shù)名,而基類構(gòu)造函數(shù)參數(shù)表中只有參數(shù)名而不包括參數(shù)類型,因?yàn)樵谶@里不是定義基類構(gòu)造函數(shù),而是調(diào)用基類構(gòu)造函數(shù)
(這里的調(diào)用和在主函數(shù)中的調(diào)用是一樣的,只是為了說明這部分參數(shù)需要用基類的構(gòu)造函數(shù)初始化),因此這些參數(shù)是實(shí)參而不是形參。它們可以是派生類構(gòu)造函數(shù)總參數(shù)列表中的參數(shù),也可以是常量和全局變量。
9、如果有多層繼承,參數(shù)列表又怎樣構(gòu)成?
這里我們給上邊的Student
類再寫一個(gè)派生類來看看
class High_Student :public Student{public: High_Student(string name, int age, string sex, string num, string high, string wife = string()) :Student(name, age, sex, num,wife) { cout << "High_Student()" << endl; _high = high; } ~High_Student() { cout<<"High_Student()"<<endl; }protected:private: string _high;};int main(){ High_Student a = { "zjh",21,"nan","1010","sss","aaa"}; a.eat(); return 0;}
我們可以看出,這里依舊是類名后邊是總參數(shù)列表,但是冒號后邊是前兩個(gè)父類的實(shí)參,我們可以將Student(name, age, sex, num,wife)
理解為嵌套調(diào)用,即執(zhí)行該語句之后,還是先調(diào)用Person
類的構(gòu)造函數(shù)初始化name、sge、sex、wife
四個(gè)參數(shù),再調(diào)用Student
類的構(gòu)造函數(shù)初始化num
.
10、C++中的隱藏是怎樣的?
還是先看代碼:
class Base{public: void fun1(int a) { cout << "Base::void fun1()" << endl; }protected:private: int _a;};class Derive :public Base{public: void fun1() { fun1(10);//這里會(huì)報(bào)錯(cuò) cout << "Derive::void fun1()"<<endl; } void fun1(int a,int b) { cout << "Derive::void fun1(int a)" << endl; }protected:private: int _b;};int main(){ Derive d; d.fun1(10);//這里會(huì)報(bào)錯(cuò),顯示沒有匹配的函數(shù)}
問題:明明子類繼承了父類只有一個(gè)參數(shù)的構(gòu)造函數(shù),為什么還不能用?
C++中規(guī)定,當(dāng)父類和子類有同名參數(shù)時(shí),子類會(huì)隱藏父類的同名函數(shù),導(dǎo)致子類對象和子類成員函數(shù)不能調(diào)用。
解決辦法:d.Base::fun1();
Base::fun1()
給函數(shù)加作用域
接下來我們再看一段代碼,通過這段代碼引出虛基類的概念:
class Base{public: Base() { a = 5; cout << "Base()" << endl; }protected: int a;};class Base1 :public Base{public: int b1; Base1() { a = a + 10; cout << "Base1()" << endl; }};class Base2 :public Base{public: int b2; Base2() { a = a + 20; cout << "Base2()" << endl; }};class Derive :public Base1, public Base2{public: int d; Derive() { cout<<"Derive a="<<a<<endl;//會(huì)報(bào)錯(cuò) }};int main(){ Derive d; return 0;}
上邊報(bào)錯(cuò)語句需要改成這樣才能成功運(yùn)行:
cout << "Base1::a=" << Base1::a << endl; cout << "Base2::a=" << Base2::a << endl;
執(zhí)行結(jié)果如下:
11、為什么這里加上作用域就能成功運(yùn)行?
在上述程序中,類Derive
是從類Base1和Base2
公有派生來的,而類Base1和Base2又
都是從類Base
公有派生而來的。雖然在類Base1和Base2
中沒有定義數(shù)據(jù)成員a
,但是它們分別都從類Base
繼承了數(shù)據(jù)成員a
,這樣在類Base1和Base2
中同時(shí)存在著數(shù)據(jù)成員a
,它們都是類Base
成員的復(fù)制。但是類Base1和Base2
中的數(shù)據(jù)成員a
具有不同的存儲(chǔ)單元,可以存放不同的數(shù)據(jù)。在程序中可以通過類Base1和Base2
去調(diào)用基類Base
的構(gòu)造函數(shù),分別對類Base1和Base2
的數(shù)據(jù)成員a
初始化。因此在Derive
的構(gòu)造函數(shù)中輸出a
的值,必須加上類名,指出是哪一個(gè)數(shù)據(jù)成員a
,否則就會(huì)出現(xiàn)二義性。(即類中的數(shù)據(jù)成員a
的值可能是Base1
中的a
,也可能是Base2
中的a
)。
圖解:
為了解決這個(gè)問題,從而有了虛基類:
先看圖解,了解虛基類是怎樣解決的
虛基類的本質(zhì)其實(shí)就是:當(dāng)基類通過多條派生路徑被一個(gè)派生類繼承時(shí),該派生類只繼承該基類一次,也就是說,基類成員只保留一次。
下面來看代碼:
class Base{public: Base() { a = 5; cout << "Base()a=" <<a<< endl; }protected: int a;};class Base1 :virtual public Base{public: int b1; Base1() { a = a + 10; cout << "Base1()a=" <<a<< endl; }};class Base2 :virtual public Base{public: int b2; Base2() { a = a + 20; cout << "Base2()a=" <<a<< endl; }};class Derive :public Base1, public Base2{public: int d; Derive() { cout << "Derive a=" << a << endl; }};int main(){ Derive d; return 0;}
執(zhí)行結(jié)果如下:
關(guān)于虛基類初始化的幾點(diǎn)說明:
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/125337.html
摘要:上面需要了解的是這倆個(gè)版本都是破蛹成蝶的版本世界挑戰(zhàn)榜咋才前三還沒擠進(jìn)去呀,你想想世界上有幾千中編程語言,在其中脫穎出來,可以說是天之嬌子,鳳毛麟角了。支持正版圖靈上面買吧,如果沒錢買盜版吧學(xué)完以后買本正版支持一下,創(chuàng)作不易是吧 ...
摘要:也就是說,一個(gè)實(shí)例變量,在的對象初始化過程中,最多可以被初始化次。當(dāng)所有必要的類都已經(jīng)裝載結(jié)束,開始執(zhí)行方法體,并用創(chuàng)建對象。對子類成員數(shù)據(jù)按照它們聲明的順序初始化,執(zhí)行子類構(gòu)造函數(shù)的其余部分。 類的拷貝和構(gòu)造 C++是默認(rèn)具有拷貝語義的,對于沒有拷貝運(yùn)算符和拷貝構(gòu)造函數(shù)的類,可以直接進(jìn)行二進(jìn)制拷貝,但是Java并不天生支持深拷貝,它的拷貝只是拷貝在堆上的地址,不同的變量引用的是堆上的...
摘要:本書主要圍繞一系列逐漸復(fù)雜的程序問題,以及用以解決這些問題的語言特性展開講解。你不只學(xué)到的函數(shù)和結(jié)構(gòu),也會(huì)學(xué)習(xí)到它們的設(shè)計(jì)目的和基本原理。因此我們把精力集中在最有價(jià)值的地方。本書不僅是對模板的權(quán)威解釋,而且本書還深入地介紹了其他一般的思想。 C++ 入門教程(41課時(shí)) - 阿里云大學(xué) C+...
摘要:繼承繼承,就是子類繼承父親的特征和行為,使得子類具有父類的成員變量和方法。此時(shí),被繼承的類稱為父類或基類,而繼承的類稱為子類或派生類。,如果存在繼承關(guān)系的時(shí)候,和就不一樣了基類中的成員可以在派生類中使用,但是基類中的成員不能再派生類中使用。 ...
摘要:月日,發(fā)布文章,介紹了年游戲項(xiàng)目的十大編程語言。無疑是游戲項(xiàng)目的最佳編程語言之一。是和等游戲引擎所使用的主要編程語言。對于游戲開發(fā)者來說,是最友好最靈活的編程語言之一。作為游戲項(xiàng)目的最佳視頻游戲編程語言之一,正在贏得屬于自己的一份榮耀。 ...
閱讀 3735·2023-01-11 11:02
閱讀 4244·2023-01-11 11:02
閱讀 3050·2023-01-11 11:02
閱讀 5180·2023-01-11 11:02
閱讀 4737·2023-01-11 11:02
閱讀 5534·2023-01-11 11:02
閱讀 5313·2023-01-11 11:02
閱讀 3986·2023-01-11 11:02