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

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

畢業(yè)設(shè)計(jì)網(wǎng)站前端代做關(guān)鍵詞seo優(yōu)化公司

畢業(yè)設(shè)計(jì)網(wǎng)站前端代做,關(guān)鍵詞seo優(yōu)化公司,新穎網(wǎng)站頁面設(shè)計(jì),如何用dw做asp動(dòng)態(tài)網(wǎng)站目錄 繼承的概念和定義 繼承的概念 繼承的定義 繼承的定義格式 繼承關(guān)系和訪問限定符 繼承基類成員訪問方式的變化 訪問權(quán)限實(shí)例 基類和派生類對(duì)象賦值轉(zhuǎn)換 繼承中的作用域 派生類的默認(rèn)成員函數(shù) 繼承與友元 繼承與靜態(tài)成員 復(fù)雜的菱形繼承及菱形虛擬繼承 繼承的…

目錄

繼承的概念和定義

繼承的概念

繼承的定義

繼承的定義格式

繼承關(guān)系和訪問限定符?

繼承基類成員訪問方式的變化

訪問權(quán)限實(shí)例

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

繼承中的作用域

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

繼承與友元

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

復(fù)雜的菱形繼承及菱形虛擬繼承


繼承的概念和定義

繼承的概念

繼承 (inheritance) 機(jī)制是面向?qū)ο蟪绦蛟O(shè)計(jì) 使代碼可以復(fù)用 的最重要的手段,它允許程序員在 持原有類特性的基礎(chǔ)上進(jìn)行擴(kuò)展 ,增加功能,這樣產(chǎn)生新的類,稱派生類。繼承 呈現(xiàn)了面向?qū)ο?/strong> 程序設(shè)計(jì)的層次結(jié)構(gòu) ,體現(xiàn)了由簡(jiǎn)單到復(fù)雜的認(rèn)知過程。以前我們接觸的復(fù)用都是函數(shù)復(fù)用, 承是類設(shè)計(jì)層次的復(fù)用。

?簡(jiǎn)單來說就是類似于在一個(gè)類中包含了另一個(gè)類的成員函數(shù)和成員變量以及對(duì)應(yīng)的訪問權(quán)限。

class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "peter"; // 姓名int _age = 18;//年齡
};
// 繼承后父類的Person的成員(成員函數(shù)+成員變量)都會(huì)變成子類的一部分。這里體現(xiàn)出了
//Student和Teacher復(fù)用了Person的成員。下面我們使用監(jiān)視窗口查看Student和Teacher對(duì)象,可
//以看到變量的復(fù)用。調(diào)用Print可以看到成員函數(shù)的復(fù)用。
class Student : public Person
{
protected:int _stuid; // 學(xué)號(hào)
};
class Teacher : public Person
{
protected:int _jobid; // 工號(hào)
};
int main()
{Student s;Teacher t;s.Print();t.Print();return 0;
}

?下面是調(diào)試結(jié)果

可以看到子類中繼承的父類的_name和_age,s和t是兩個(gè)不同的類;他們各自繼承的父類的內(nèi)存空間也是不同的,就像每個(gè)孩子繼承父親的家產(chǎn)一樣。

繼承的定義

繼承的定義格式

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

繼承關(guān)系和訪問限定符?

繼承基類成員訪問方式的變化

總結(jié):

1. 基類 private 成員在派生類中無論以什么方式繼承都是不可見的。這里的 不可見是指基類的私
有成員還是被繼承到了派生類對(duì)象中,但是語法上限制派生類對(duì)象不管在類里面還是類外面
都不能去訪問它
2. 基類 private 成員在派生類中是不能被訪問,如果基類成員不想在類外直接被訪問,但需要在
派生類中能訪問,就定義為 protected 。 可以看出保護(hù)成員限定符是因繼承才出現(xiàn)的 。
3. 實(shí)際上面的表格我們進(jìn)行一下總結(jié)會(huì)發(fā)現(xiàn),基類的私有成員在子類都是不可見?;惖钠渌?
成員在子類的訪問方式 == Min( 成員在基類的訪問限定符,繼承方式 ) public > protected
> private 。
4. 使用關(guān)鍵字 class 時(shí)默認(rèn)的繼承方式是 private ,使用 struct 時(shí)默認(rèn)的繼承方式是 public 不過
最好顯示的寫出繼承方式 。
5. 在實(shí)際運(yùn)用中一般使用都是 public 繼承,幾乎很少使用 protetced/private 繼承 ,也不提倡
使用 protetced/private 繼承,因?yàn)?/span> protetced/private 繼承下來的成員都只能在派生類的類里
面使用,實(shí)際中擴(kuò)展維護(hù)性不強(qiáng)。

訪問權(quán)限實(shí)例

class Person
{
public:void Print(){cout << _name << endl;}
protected:string _name; // 姓名
private:int _age; // 年齡
};
//class Student : protected Person
//class Student : private Person
class Student : public Person
{void fun(){cout << _stunum << " " << _age << " " << _name; 這里_age顯示無法訪問}
protected:int _stunum; // 學(xué)號(hào)
};int main()
{Student s;    s.Print();   return 0;
}

在上述代碼中,Student是以public的形式繼承的父類person,最父類成員函數(shù)、成員變量的訪問權(quán)限依次是public.protected和private。protected的對(duì)象是可以進(jìn)行訪問的。

class Person
{
public:void Print(){cout << _name << endl;}
protected:string _name; // 姓名
private:int _age; // 年齡
};
//class Student : protected Person
//class Student : private Person
class Student : protected Person
{void fun(){cout << _stunum << " " << _age << " " << _name; //顯示不可訪問_name = 6;    }
protected:int _stunum; // 學(xué)號(hào)
};int main()
{Student s;    s.Print();   //顯示不可訪問 return 0;
}

?在上述代碼中,以protected的形式繼承父類時(shí),對(duì)父類的成員函數(shù)。成員變量的訪問權(quán)限依次是protected.protected和private。print()函數(shù)無法再類外進(jìn)行調(diào)用。

如果以private 的形式繼承父類,那么父類的所有成員的訪問權(quán)限都是private,在子類中都無法進(jìn)行訪問;

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

派生類對(duì)象 可以賦值給 基類的對(duì)象 / 基類的指針 / 基類的引用 。這里有個(gè)形象的說法叫切片
或者切割。寓意把派生類中父類那部分切來賦值過去。
基類對(duì)象不能賦值給派生類對(duì)象。
基類的指針或者引用可以通過強(qiáng)制類型轉(zhuǎn)換賦值給派生類的指針或者引用。但是必須是基類
的指針是指向派生類對(duì)象時(shí)才是安全的。這里基類如果是多態(tài)類型,可以使用 RTTI(Run
Time Type Information) dynamic_cast 來進(jìn)行識(shí)別后進(jìn)行安全轉(zhuǎn)換。
class Person
{
protected:string _name; // 姓名string _sex; ?// 性別int _age; // 年齡
};
class Student : public Person
{
public:int _No; // 學(xué)號(hào)
};
void Test()
{Student sobj;// 1.子類對(duì)象可以賦值給父類對(duì)象/指針/引用Person pobj = sobj;Person* pp = &sobj;Person& rp = sobj;//2.基類對(duì)象不能賦值給派生類對(duì)象sobj = pobj;    // 3.基類的指針可以通過強(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ì)存在越界訪問的問題ps2->_No = 10;
}

繼承中的作用域

1. 在繼承體系中 基類 派生類 都有 獨(dú)立的作用域 。
2. 子類和父類中有同名成員, 子類成員將屏蔽父類對(duì)同名成員的直接訪問,這種情況叫隱藏,
也叫重定義。 (在子類成員函數(shù)中,可以 使用 基類 :: 基類成員 顯示訪問
3. 需要注意的是如果是成員函數(shù)的隱藏,只需要函數(shù)名相同就構(gòu)成隱藏。
4. 注意在實(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();
};

?子類和父類中都有_num但是他們的作用域不同,在子類中只能訪問子類的_num,當(dāng)然也可以通person類訪問父類的_num,

// 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);
};

在子類中,只能直接訪問帶參數(shù)的fun,可以通過person::fun()來訪問無參數(shù)的fun。? ? ? ??

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

6 個(gè)默認(rèn)成員函數(shù), 默認(rèn) 的意思就是指我們不寫,編譯器會(huì)變我們自動(dòng)生成一個(gè),那么在派生類
中,這幾個(gè)成員函數(shù)是如何生成的呢?
1. 派生類的構(gòu)造函數(shù)必須調(diào)用基類的構(gòu)造函數(shù)初始化基類的那一部分成員。如果基類沒有默認(rèn)
的構(gòu)造函數(shù),則必須在派生類構(gòu)造函數(shù)的初始化列表階段顯示調(diào)用。
2. 派生類的拷貝構(gòu)造函數(shù)必須調(diào)用基類的拷貝構(gòu)造完成基類的拷貝初始化。
3. 派生類的 operator= 必須要調(diào)用基類的 operator= 完成基類的復(fù)制。
4. 派生類的析構(gòu)函數(shù)會(huì)在被調(diào)用完成后自動(dòng)調(diào)用基類的析構(gòu)函數(shù)清理基類成員。因?yàn)檫@樣才能
保證派生類對(duì)象先清理派生類成員再清理基類成員的順序。
5. 派生類對(duì)象初始化先調(diào)用基類構(gòu)造再調(diào)派生類構(gòu)造。
6. 派生類對(duì)象析構(gòu)清理先調(diào)用派生類析構(gòu)再調(diào)基類的析構(gòu)。
7. 因?yàn)楹罄m(xù)一些場(chǎng)景析構(gòu)函數(shù)需要構(gòu)成重寫,重寫的條件之一是函數(shù)名相同 ( 這個(gè)我們后面會(huì)講
) 。那么編譯器會(huì)對(duì)析構(gòu)函數(shù)名進(jìn)行特殊處理,處理成 destrutor() ,所以父類析構(gòu)函數(shù)不加
virtual 的情況下,子類析構(gòu)函數(shù)和父類析構(gòu)函數(shù)構(gòu)成隱藏關(guān)系。
class Person
{
public:Person(const char* name = "peter"): _name(name){cout << "Person()" << endl;}Person(const Person& p): _name(p._name){cout << "Person(const Person& p)" << endl;}Person& operator=(const Person& p){cout << "Person operator=(const Person& p)" << endl;if (this != &p)_name = p._name;return *this;}~Person(){cout << "~Person()" << endl;}
protected:string _name; // 姓名
};
class Student : public Person
{
public:Student(const char* name, int num): Person(name), _num(num){cout << "Student()" << endl;}Student(const Student& s): Person(s), _num(s._num){cout << "Student(const Student& s)" << endl;}Student& operator = (const Student& s){cout << "Student& operator= (const Student& s)" << endl;if (this != &s){Person::operator =(s);_num = s._num;}return *this;}~Student(){cout << "~Student()" << endl;}
protected:int _num; //學(xué)號(hào)
};
void Test()
{Student s1("jack", 18);Student s2(s1);  Student s3("rose", 17);  s1 = s3;  
}

其實(shí)可以把父類當(dāng)成一個(gè)自定義類型的成員變量,如果父類有默認(rèn)構(gòu)造函數(shù),那么就是自己自動(dòng)調(diào)用,如果沒有需要手動(dòng)在子類的構(gòu)造函數(shù)的初始化列表中進(jìn)行傳參數(shù)初始化。析構(gòu)函數(shù)會(huì)自動(dòng)調(diào)用??截悩?gòu)造需要再子類的拷貝構(gòu)造函數(shù)中的初始化列表中進(jìn)行調(diào)用。

繼承與友元

友元關(guān)系不能繼承 ,也就是說基類友元不能訪問子類私有和保護(hù)成員。
class Student;
class Person
{
public:friend void Display(const Person& p, const Student& s);
protected:string _name; // 姓名
};
class Student : public Person
{
protected:int _stuNum; // 學(xué)號(hào)
};
void Display(const Person& p, const Student& s)
{cout << p._name << endl;cout << s._stuNum << endl;
}
void main()
{Person p;Student s;Display(p, s);
}

在父類中的友元只能訪問父類的成員變量,無法訪問子類的成員變量。

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

基類定義了 static 靜態(tài)成員,則整個(gè)繼承體系里面只有一個(gè)這樣的成員 。無論派生出多少個(gè)子
類,都只有一個(gè) static 成員實(shí)例 。
class Person
{
public:Person() { ++_count; }
protected:string _name; // 姓名
public:static int _count; // 統(tǒng)計(jì)人的個(gè)數(shù)。
};
int Person::_count = 0;
class Student : public Person
{
protected:int _stuNum; // 學(xué)號(hào)
};
class Graduate : public Student
{
protected:string _seminarCourse; // 研究科目
};
void TestPerson()
{Student s1;Student s2;Student s3;Graduate s4;cout << " 人數(shù) :" << Person::_count << endl;Student::_count = 0;cout << " 人數(shù) :" << Person::_count << endl;
}

所有的實(shí)例化的繼承類都公用這一個(gè)靜態(tài)成員變量。

復(fù)雜的菱形繼承及菱形虛擬繼承

單繼承:一個(gè)子類只有一個(gè)直接父類時(shí)稱這個(gè)繼承關(guān)系為單繼承。
多繼承:一個(gè)子類有兩個(gè)或以上直接父類時(shí)稱這個(gè)繼承關(guān)系為多繼承。
菱形繼承:菱形繼承是多繼承的一種特殊情況。
菱形繼承的問題:從下面的對(duì)象成員模型構(gòu)造,可以看出菱形繼承有數(shù)據(jù)冗余和二義性的問題。
Assistant 的對(duì)象中 Person 成員會(huì)有兩份。
class Person
{
public:string _name; // 姓名
};
class Student : public Person
{
protected:int _num; //學(xué)號(hào)
};
class Teacher : public Person {
protected:int _id; // 職工編號(hào)
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修課程
};
void Test()
{// 這樣會(huì)有二義性無法明確知道訪問的是哪一個(gè)Assistant a;a._name = "peter";// 需要顯示指定訪問哪個(gè)父類的成員可以解決二義性問題,但是數(shù)據(jù)冗余問題無法解決a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}

Teacher和Student類中各有一份person父類,實(shí)際上只需要有一分就可以了,

虛擬繼承可以解決菱形繼承的二義性和數(shù)據(jù)冗余的問題。如上面的繼承關(guān)系,在 Student
Teacher 的繼承 Person 時(shí)使用虛擬繼承,即可解決問題。需要注意的是,虛擬繼承不要在其他地
方去使用。
class Person
{
public:string _name; // 姓名
};
class Student : virtual public Person
{
protected:int _num; //學(xué)號(hào)
};
class Teacher : virtual public Person
{
protected:int _id; // 職工編號(hào)
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修課程
};
void Test()
{Assistant a;a._name = "peter";
}

在重復(fù)的父類訪問前加上virtual,進(jìn)行虛擬化,Student和Teacher就會(huì)公用person類了,就解決了繼承的二義性和數(shù)據(jù)冗余的問題。

總結(jié):

1. 很多人說 C++ 語法復(fù)雜,其實(shí)多繼承就是一個(gè)體現(xiàn)。有了多繼承 ,就存在菱形繼承,有了菱形繼承就有菱形虛擬繼承,底層實(shí)現(xiàn)就很復(fù)雜。所以一般不建議設(shè)計(jì)出多繼承,一定不要設(shè)計(jì)出菱形繼承。否則在復(fù)雜度及性能上都有問題。
2. 多繼承可以認(rèn)為是 C++ 的缺陷之一,很多后來的 OO 語言都沒有多繼承,如 Java
3. 繼承和組合
public 繼承是一種 is-a 的關(guān)系。也就是說每個(gè)派生類對(duì)象都是一個(gè)基類對(duì)象。
組合是一種 has-a 的關(guān)系。假設(shè) B 組合了 A ,每個(gè) B 對(duì)象中都有一個(gè) A 對(duì)象。
優(yōu)先使用對(duì)象組合,而不是類繼承 。
繼承允許你根據(jù)基類的實(shí)現(xiàn)來定義派生類的實(shí)現(xiàn)。這種通過生成派生類的復(fù)用通常被稱為白箱復(fù)用(white-box reuse) 。術(shù)語 白箱 是相對(duì)可視性而言:在繼承方式中,基類的內(nèi)部細(xì)節(jié)對(duì)子類可見 。繼承一定程度破壞了基類的封裝,基類的改變,對(duì)派生類有很大的影響。派生類和基類間的依賴關(guān)系很強(qiáng),耦合度高。
對(duì)象組合是類繼承之外的另一種復(fù)用選擇。新的更復(fù)雜的功能可以通過組裝或組合對(duì)象來獲得。對(duì)象組合要求被組合的對(duì)象具有良好定義的接口。這種復(fù)用風(fēng)格被稱為黑箱復(fù)用(black-box reuse) ,因?yàn)閷?duì)象的內(nèi)部細(xì)節(jié)是不可見的。對(duì)象只以 黑箱 的形式出現(xiàn)。
組合類之間沒有很強(qiáng)的依賴關(guān)系,耦合度低。優(yōu)先使用對(duì)象組合有助于你保持每個(gè)類被封裝。
實(shí)際盡量多去用組合。組合的耦合度低,代碼維護(hù)性好。不過繼承也有用武之地的,有些關(guān)系就適合繼承那就用繼承,另外要實(shí)現(xiàn)多態(tài),也必須要繼承。類之間的關(guān)系可以用繼承,可以用組合,就用組合。
http://www.risenshineclean.com/news/49131.html

相關(guān)文章:

  • 可以自己買個(gè)服務(wù)器做網(wǎng)站嗎自助建站系統(tǒng)模板
  • 南充城市建設(shè)投訴網(wǎng)站百度如何注冊(cè)公司網(wǎng)站
  • 公司展廳設(shè)計(jì)策劃優(yōu)化網(wǎng)站視頻
  • 企業(yè)快速建站都有哪些技巧呢seo免費(fèi)優(yōu)化工具
  • 在線網(wǎng)站轉(zhuǎn)app深圳seo優(yōu)化推廣公司
  • ipv6跟做網(wǎng)站有關(guān)嗎培訓(xùn)心得體會(huì)100字
  • 網(wǎng)站建設(shè)濟(jì)南有做的嗎他達(dá)拉非片和偉哥區(qū)別
  • 網(wǎng)站開始開發(fā)階段的主要任務(wù)提供seo顧問服務(wù)適合的對(duì)象是
  • 大學(xué)生心里健康網(wǎng)站設(shè)計(jì)與建設(shè)自助建站系統(tǒng)哪個(gè)好用
  • 怎么建設(shè)微信網(wǎng)站南寧百度推廣seo
  • 二級(jí)域名著名網(wǎng)站logo網(wǎng)站設(shè)計(jì)
  • 建設(shè)企業(yè)網(wǎng)站多少錢全國(guó)網(wǎng)站排名
  • b2b2c電商平臺(tái)開發(fā)長(zhǎng)沙seo外包平臺(tái)
  • 做網(wǎng)站那里好名站在線
  • wordpress 畫廊 插件西安做推廣優(yōu)化的公司
  • 自己做網(wǎng)站還能掙錢嗎2023年6月份又封城了
  • 手機(jī)wap購(gòu)物網(wǎng)站模板seo排名優(yōu)化推薦
  • 新的網(wǎng)站建設(shè)技術(shù)方案東莞企業(yè)網(wǎng)站設(shè)計(jì)公司
  • wordpress建立商城杭州關(guān)鍵詞優(yōu)化平臺(tái)
  • 通過ip訪問網(wǎng)站需要怎么做詞愛站的關(guān)鍵詞
  • 免費(fèi)b站推廣網(wǎng)站不用下載長(zhǎng)沙網(wǎng)站托管seo優(yōu)化公司
  • 1.1做網(wǎng)站的目的一個(gè)新產(chǎn)品的營(yíng)銷方案
  • 做網(wǎng)站賺錢嗎免費(fèi)數(shù)據(jù)查詢網(wǎng)站
  • 做app網(wǎng)站的公司seo關(guān)鍵詞排名技巧
  • 瀘州網(wǎng)站建設(shè)北京網(wǎng)站建設(shè)優(yōu)化
  • 網(wǎng)站建設(shè)需要政府集中采購(gòu)嗎免費(fèi)廣告投放網(wǎng)站
  • 網(wǎng)站怎么上傳數(shù)據(jù)庫(kù)淺議網(wǎng)絡(luò)營(yíng)銷論文
  • 網(wǎng)站創(chuàng)作情感營(yíng)銷
  • 珠海網(wǎng)站建設(shè)排名含有友情鏈接的網(wǎng)頁
  • 軟件公司網(wǎng)站源碼如何做好seo優(yōu)化