欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++繼承的定義與注意事項(xiàng)

 更新時(shí)間:2021年05月11日 09:48:04   作者:程序字母K  
這篇文章主要給大家介紹了關(guān)于C++繼承的定義與注意事項(xiàng)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、什么是繼承?

1.1、概念

**繼承(inheritance)機(jī)制是面向?qū)ο蟪绦蛟O(shè)計(jì)使代碼可以復(fù)用的最重要的手段,它允許程序員在保持原有類特性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加功能,這樣產(chǎn)生新的類,稱派生類。

1.2、定義

下面我們看到Person是父類,也稱作基類。Student是子類,也稱作派生類

1.2.1、繼承關(guān)系和訪問(wèn)限定符

1.2.2、繼承基類成員訪問(wèn)方式的變化

// 實(shí)例演示三種繼承關(guān)系下基類成員的各類型成員訪問(wèn)關(guān)系的變化
class Person
{
public :
void Print ()
{
cout<<_name <<endl;
}
protected :
string _name ; // 姓名
private :
int _age ; // 年齡
};
//三種繼承方式,對(duì)應(yīng)上面圖表
//class Student : protected Person
//class Student : private Person
class Student : public Person
{
protected :
int _stunum ; // 學(xué)號(hào)
};

注意:

1.基類private成員在派生類中無(wú)論以什么方式繼承都是不可見(jiàn)的。不可見(jiàn)是指基類的私有成員還是被繼承到了派生類對(duì)象中,但是語(yǔ)法上派生類對(duì)像無(wú)法訪問(wèn);

2.使用關(guān)鍵字class時(shí)默認(rèn)的繼承方式是private,使用struct時(shí)默認(rèn)的繼承方式是public,不過(guò)最好顯示的寫(xiě)出繼承方式;

3. 在實(shí)際運(yùn)用中一般使用都是public繼承,不提倡使protetced/private繼承,因?yàn)閜rotetced/private繼承下來(lái)的成員都只能在派生類的類里面使用,實(shí)際中擴(kuò)展維護(hù)性不強(qiáng);

二、基類和派生類對(duì)象賦值轉(zhuǎn)換

派生類(子類)對(duì)象可以賦值給基類(父類)對(duì)象/指針/引用;

即將父類中那部分賦值給基類;

這里有個(gè)形象的說(shuō)法叫切片或者切割。寓意把派生類中父類那部分切來(lái)賦值過(guò)去。

基類對(duì)象不能賦值給派生類對(duì)象;

基類的指針可以通過(guò)強(qiáng)制類型轉(zhuǎn)換賦值給派生類的指針。但是必須是基類的指針是指向派生類對(duì)象時(shí)才是安全的。這里基類如果是多態(tài)類型,可以使用RTTI(Run-Time Type Information)的dynamic_cast 來(lái)進(jìn)行識(shí)別后進(jìn)行安全轉(zhuǎn)換;

Student sobj ;
// 1.子類對(duì)象可以賦值給父類對(duì)象/指針/引用
Person pobj = sobj ;
Person* pp = &sobj;
Person& rp = sobj;
//2.基類對(duì)象不能賦值給派生類對(duì)象
sobj = pobj;//錯(cuò)誤
// 3.基類的指針可以通過(guò)強(qiáng)制類型轉(zhuǎn)換賦值給派生類的指針
pp = &sobj
Student* ps1 = (Student*)pp; // 這種情況轉(zhuǎn)換時(shí)可以的。
ps1->_No = 10;
pp = &pobj;
Student* ps2 = (Student*)pp; // 這種情況轉(zhuǎn)換時(shí)雖然可以,但是會(huì)存在越界訪問(wèn)的問(wèn)題
ps2->_No = 10;

三、繼承中的作用域

  1. 在繼承體系中基類和派生類都有獨(dú)立的作用域。
  2. 子類和父類中有同名成員,子類成員將屏蔽父類對(duì)同名成員的直接訪問(wèn),這種情況叫隱藏,也叫重定
  3. 義。(在子類成員函數(shù)中,可以使用 基類::基類成員 顯示訪問(wèn))
  4. 需要注意的是如果是成員函數(shù)的隱藏,只需要函數(shù)名相同就構(gòu)成隱藏。
  5. 注意在實(shí)際中在繼承體系里面最好不要定義同名的成員。
 // Student的_num和Person的_num構(gòu)成隱藏關(guān)系,可以看出這樣代碼雖然能跑,但是非常容易混淆
class Person
{
protected :
string _name = "小李子"; // 姓名
int _num = 111; // 身份證號(hào)
};
class Student : public Person
{
public:
void Print()
{
cout<<" 姓名:"<<_name<< endl;
cout<<" 身份證號(hào):"<<Person::_num<< endl;
cout<<" 學(xué)號(hào):"<<_num<<endl;
}
protected:
int _num = 999; // 學(xué)號(hào)
};
void Test()
{
Student s1;
s1.Print();
};
// B中的fun和A中的fun不是構(gòu)成重載,因?yàn)椴皇窃谕蛔饔糜?
// B中的fun和A中的fun構(gòu)成隱藏,成員函數(shù)滿足函數(shù)名相同就構(gòu)成隱藏。
class A
{
public:
void fun()
{
cout << "func()" << endl;
}
};
class B : public A
{
public:
void fun(int i)

{
A::fun();
cout << "func(int i)->" <<i<<endl;
}
};
void Test()
{
B b;
b.fun(10);
};

四、派生類的默認(rèn)成員函數(shù)

6個(gè)默認(rèn)成員函數(shù),“默認(rèn)”的意思就是指我們不寫(xiě),編譯器會(huì)變我們自動(dòng)生成一個(gè),那么在派生類中,這幾個(gè)
成員函數(shù)是如何生成的呢?

  1. 派生類的構(gòu)造函數(shù)必須調(diào)用基類的構(gòu)造函數(shù)初始化基類的那一部分成員。如果基類沒(méi)有默認(rèn)的構(gòu)造函
  2. 數(shù),則必須在派生類構(gòu)造函數(shù)的初始化列表階段顯示調(diào)用。
  3. 派生類的拷貝構(gòu)造函數(shù)必須調(diào)用基類的拷貝構(gòu)造完成基類的拷貝初始化。
  4. 派生類的operator=必須要調(diào)用基類的operator=完成基類的復(fù)制。
  5. 派生類的析構(gòu)函數(shù)會(huì)在被調(diào)用完成后自動(dòng)調(diào)用基類的析構(gòu)函數(shù)清理基類成員。因?yàn)檫@樣才能保證派生類
  6. 對(duì)象先清理派生類成員再清理基類成員的順序。
  7. 派生類對(duì)象初始化先調(diào)用基類構(gòu)造再調(diào)派生類構(gòu)造。
  8. 派生類對(duì)象析構(gòu)清理先調(diào)用派生類析構(gòu)再調(diào)基類的析構(gòu)。


五、繼承與友元

友元關(guān)系不能繼承,也就是說(shuō)基類友元不能訪問(wèn)子類私有和保護(hù)成員;

六、繼承與靜態(tài)成員

基類定義了static靜態(tài)成員,則整個(gè)繼承體系里面只有一個(gè)這樣的成員;

七、菱形繼承

單繼承:一個(gè)子類只有一個(gè)直接父類

多繼承:一個(gè)子類有兩個(gè)或以上直接父類時(shí)稱這個(gè)繼承關(guān)系為多繼承

菱形繼承:菱形繼承是多繼承的一種特殊情況。

菱形繼承的問(wèn)題:從下面的對(duì)象成員模型構(gòu)造,可以看出菱形繼承有數(shù)據(jù)冗余和二義性的問(wèn)題。在Assistant的對(duì)象中Person成員會(huì)有兩份。

虛擬繼承可以解決菱形繼承的二義性和數(shù)據(jù)冗余的問(wèn)題,在Student和Teacher的繼承;

加關(guān)鍵字:virtual

菱形繼承的內(nèi)存對(duì)象成員模型:這里可以看到數(shù)據(jù)冗余

菱形虛擬繼承的內(nèi)存對(duì)象成員模型:這里可以分析出D對(duì)象中將A放到的了對(duì)象組成的最下面,這個(gè)A同時(shí)屬于B和C,那么B和C如何去找到公共的A呢?

這里是通過(guò)了B和C的兩個(gè)指針,指向的一張表。這兩個(gè)指針叫虛基表指針,這兩個(gè)表叫虛基表。虛基表中存的偏移量。通過(guò)偏移量可以找到下面的A。

虛基表:存放偏移量

八、繼承和組合

public繼承是一種is-a的關(guān)系。也就是說(shuō)每個(gè)派生類對(duì)象都是一個(gè)基類對(duì)象,高耦合;

組合是一種has-a的關(guān)系。假設(shè)B組合了A,每個(gè)B對(duì)象中都有一個(gè)A對(duì)象,低耦合;

優(yōu)先使用對(duì)象組合,而不是類繼承

繼承和耦合的使用:

// Car和BMW Car和Benz構(gòu)成is-a的關(guān)系
class Car{
protected:
string _colour = "白色"; // 顏色
string _num = "陜ABIT00"; // 車牌號(hào)
};
class BMW : public Car{
public:
void Drive() {cout << "好開(kāi)-操控" << endl;}
};
class Benz : public Car{
public:
void Drive() {cout << "好坐-舒適" << endl;}
};
// Tire和Car構(gòu)成has-a的關(guān)系
class Tire{
protected:
string _brand = "Michelin"; // 品牌
size_t _size = 17; // 尺寸
};
class Car{
protected:
string _colour = "白色"; // 顏色
string _num = "陜ABIT00"; // 車牌號(hào)
Tire _t; // 輪胎
};

總結(jié)

到此這篇關(guān)于C++繼承的定義與注意事項(xiàng)的文章就介紹到這了,更多相關(guān)C++繼承內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論