[TOC]
目前創(chuàng)新互聯(lián)建站已為上千余家的企業(yè)提供了網(wǎng)站建設(shè)、域名、雅安服務(wù)器托管、網(wǎng)站托管運(yùn)營、企業(yè)網(wǎng)站設(shè)計(jì)、恒山網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
繼承是面向?qū)?em>復(fù)用的重要手段。通過繼承定義一個類,繼承是類型之間的關(guān)系建模,共享公有的東西,實(shí)現(xiàn)各自本質(zhì)不同的東西。
三種繼承關(guān)系下基類成員的在派生類的訪問關(guān)系變化(圖)
舉個栗子(公有繼承)
```c++
class Person
{
public :
Person(const string& name)
: _name(name )
{}
void Display ()
{
cout<<_name <<endl;
}
protected :
string _name ; // 姓名
string _sex ;
};
class Student : public Person //公有繼承
{
protected :
int _num ; // 學(xué)號
};
### 繼承圖例解釋:

**私有繼承和保護(hù)繼承很少用到,我們重點(diǎn)要掌握公有繼承**
### 繼承與轉(zhuǎn)換--賦值兼容規(guī)則--public繼承
1. 子類對象可以賦值給父類對象(切割/切片)
2. 父類對象不能賦值給子類對象
3. 父類的指針/引用可以指向子類對象
4. 子類的指針/引用不能指向父類對象(可以通過強(qiáng)制類型轉(zhuǎn)換完成)
```C++
class Person
{
public:
void Display()
{
cout << "AA" << endl;
}
protected:
string _name; // 姓名
};
class Student : public Person
{
public:
int _num; // 學(xué)號
};
int main()
{
Person a;
Student b;
a = b; //子類對象賦值給基類對象(切片)這個特性是編譯器支持的
b = a; //父類對象不能賦值給子類對象
Person *p1 = &b; //特性3
//Person &a1 = b; //特性3
Student *p2 = (Student*)&a; //特性4
Student& b1 = (Student&)a; //特性4
getchar();
return 0;
}
class Person
{
public:
Person(const char *name = "",int num = 0)
:_name(name)
,_num(num)
{}protected:
string _name; // 姓名
int _num;
};
class Student : public Person
{
public:
Student(const char* name = "", const int num1 = 0, int num2 = 0)
:Person(name,num1)
,_num(num2)
{}
void Display()
{
cout << _num << endl;
cout <<Person:: _num << endl;//必須顯示指出基類作用域才能打印基類成員
}
protected:
int _num; // 學(xué)號
};
int main()
{
Person a("boday",15);
Student b("crash",1502,17);
b.Display();
return 0;}
**運(yùn)行結(jié)果:**

可以很明顯看出此時(shí)打印的是子類的成員,而隱藏掉了父類的成員,(```這就是隱藏```)
### 派生類的默認(rèn)成員函數(shù)
 在繼承關(guān)系里面,在派生類中如果沒有顯示定義這六個成員函數(shù),編譯系統(tǒng)則會默認(rèn)合成這六個默認(rèn)的成員函數(shù)。

**來個栗子說說默認(rèn)成員函數(shù)的前四個(` 后兩個不常用`)**
```cpp
class Person
{
public:
Person(const char *name = "",int num = 0) //父類構(gòu)造函數(shù)
:_name(name)
,_num(num)
{}
~Person()//父類析構(gòu)函數(shù)
{
cout << "~Person()" << endl;
}
Person(const Person& p)//父類拷貝構(gòu)造函數(shù)
:_name(p._name)
,_num(p._num)
{}
Person& operator=(const Person& p)//父類賦值運(yùn)算符重載
{
if (this != &p)
{
_name = p._name;
_num = p._num;
}
return *this;
}
protected:
string _name; // 姓名
int _num;
};
class Student : public Person
{
public:
Student(const char* name = "", const int num1 = 0, int num2 = 0)//子類構(gòu)造函數(shù)
:Person(name,num1)
,_num(num2)
{}
~Student()//子類析構(gòu)函數(shù)
{
cout << "~Student()" << endl;
}
Student(const Student& s)//子類拷貝構(gòu)造函數(shù)
:Person(s)
,_num(s._num)
{}
Student& operator=(const Student& s)//子類賦值運(yùn)算符重載
{
Person::operator=(s); //顯示調(diào)用父類賦值運(yùn)算符重載
_num = s._num;
}
protected:
int _num; // 學(xué)號
};先調(diào)用父類構(gòu)造函數(shù),在調(diào)用基類構(gòu)造函數(shù);析構(gòu)函數(shù)調(diào)用順序與構(gòu)造函數(shù)相反(先構(gòu)造后析構(gòu),這個和棧的規(guī)則有關(guān)(先入后出))
class A
{
protected:
int _a;
};
class B : public A //B類 繼承 A類
{
protected:
int _b;
};
直接父類時(shí)稱這個繼承關(guān)系為多繼承class A
{
protected:
int _a;
};
class B
{
protected:
int _b;
};
class C : public A,B
{
protected:
int _c;
};
class Person
{
public:
string _name; // 姓名
};
class Student : public Person
{
protected:
int _num; //學(xué)號
};
class Teacher : public Person
{
protected:
int _id; // 職工編號
};
class Assistant : public Student, public Teacher
{
protected:
string _majorCourse; // 主修課程
};
void Test()
{
// 顯示指定訪問哪個父類的成員(二義性問題)
Assistant a;
a.Student::_name = "xxx";
a.Teacher::_name = "yyy";//數(shù)據(jù)冗余問題
}很明顯菱形繼承存在問題,存在二義性和數(shù)據(jù)冗余的問題。為了解決這個問題就引入了虛繼承。
在聲明派生類時(shí),指定其繼承方式時(shí)聲明為虛繼承的方式。如
class A
{
public:
int _a;
};
class B : virtual public A //聲明為虛基類
{
protected:
int _b;
};
class C : virtual public A //聲明為虛基類
{
protected:
int _c;
};
class D : public B,public C
{
protected:
int _d;
};看看測試效果:
void Test()
{
D d;
d._a = 10;
}
是不是很疑惑到底是如何解決的?那就要深入到底層探索下
這里在虛繼承時(shí)用一個虛基表存放偏移量,這樣B和C類同時(shí)使用一個虛基表存放A相對于B和C的偏移量,當(dāng)發(fā)生虛繼承時(shí)A會存放在一個公共區(qū)域,這就很好的解決了二義性問題,同時(shí)也節(jié)省了空間。
虛繼承很好的解決了菱形繼承帶來的問題。
這里建議大家寫下代碼調(diào)試一下,同時(shí)查看內(nèi)存變化。
網(wǎng)站標(biāo)題:C++中的繼承詳解
網(wǎng)頁網(wǎng)址:http://www.chinadenli.net/article42/ipphhc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動網(wǎng)站建設(shè)、網(wǎng)站營銷、網(wǎng)站內(nèi)鏈、營銷型網(wǎng)站建設(shè)、企業(yè)建站、網(wǎng)站收錄
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)