【C++學習筆記二】C++繼承

繼承

繼承允許我們一句另一個類來定義一個類,這使得繼承和維護一個程序變得更加容易,也達到了重用代碼功能和提高執行效率的效果。

一般格式為:

class 派生類名 :訪問修飾符 基類名{};

其中訪問修飾符是public protected private中的一個,默認為private

派生類可以訪問基類中所有的非私有成員,因此基類成員如果不想被派生類的成員訪問,則應該在基類聲明為private

一個派生類繼承了所有的基類非私有方法,但是下列情況除外:

  • 基類的構造函數,析構函數和拷貝構造函數
  • 基類的重載運算符
  • 基類的友元函數

繼承類型

  • 公有繼承:基類的公有成員也是派生類的公有成員,基類的保護成員也是派生類的保護乘員胡安,基類的私有成員不能直接被派生類訪問,但是可以通過基類的公有和保護方法來訪問。
  • 保護繼承:基類的公有和保護成員將成為派生類的保護成員
  • 私有繼承:公有和保護成員將稱為派生類的私有成員

多繼承

一個子類可以有多個父類,繼承了多個父類的特性,不同父類用逗號隔開。

class <派生類名>:<繼承方式><基類名>,<繼承方式>,<基類名><繼承方式><基類名>,..
{};

虛繼承

因為C++多繼承的特性,當從兩個方向繼承到同一個類的時候就可能會出現拷貝了兩份相同數據的問題,這個時候訪問被拷貝多份的數據成員如果沒有加名字空間編譯器就會報錯,因為不確定到底訪問的是哪一份變量。為了解決這個問題,我們要使用虛繼承從而實現只拷貝一份變量。需要注意的一點是,虛繼承是指對多個類繼承一個類的時候需要進行虛繼承,這樣就能解決一個類繼承這多個類的時候出現的成員重復。

具體見樣例:

class A{};
class B:virtual public A{};
class C:virtual public A{};
class D:public B,public C{};//注意對D來講用virtual已經晚了,我們在上面個多個類繼承A的時候用虛繼承,這樣有其他類繼承B,C等的時候就不會出現問題。

繼承機理

編譯器先通過基類的構造函數創建一個基類的對象,然后再通過派生類的構造函數在后面加上派生類的成員,并進行初始化。基類中私有成員對派生類不可見,但是派生類對象可以通過父類提供的接口對父類中的對象進行訪問。實際上派生類成員是含有基類中的所有的成員的。

對于相同名字的數據成員,通過基類方法改變的是基類的數據成員,通過派生類方法改變的是派生類數據成員。如果想要訪問基類的(公有)成員可以使用名字空間。

可以由以下測試看出:


#include<iostream>
#include<cstdio>using namespace std;class A
{int a[100];
public:int b;
};
class B :public A
{//int c[50];int d;
};int main()
{B a;printf("%d", sizeof(a));return 0;
}

運行結果:
在這里插入圖片描述
顯然派生類中含有基類的私有成員,只是不可以直接訪問。

派生類的構造函數

詳見另一篇文章:構造函數,作者講的很好。

在每次派生類構造函數調用時,首先會調用父類的構造函數,然后再調用派生類的構造函數,最后先調用派生類的析構函數,最后調用父類的析構函數。

在每個派生類構造函數中,如果我們要使用父類的有參構造函數,則需要在函數頭部調用。如果我們沒有顯式地調用父類的構造函數則編譯器會自動在派生類構造函數開頭調用基類的無參構造函數。(如果基類只有有參構造函數編譯器會因為找不到無參構造函數而報錯)。

顯式調用的格式如下:

class A
{public:A(int x){}
};
class B:public A
{
public:
B():A(x)//只可以在這一個地方顯式調用
{}
};

在其他地方顯式調用都是沒有意義的。(相當于創建了一個沒有辦法引用的父類)
見下例:


#include<iostream>
#include<cstdio>using namespace std;class A
{int a[100];
public:A(){printf("調用了無參構造函數\n");}~A(){printf("調用了析構函數\n");}A(int x){printf("調用了有參構造函數\n");a[0] = x;}int b;
};
class B :public A
{//int c[50];int d;
public:B(){A(5);printf("test\n");d = 0;}void Print(){printf("Hello world!\n");}
};int main()
{B* a=new B();printf("%d\n", sizeof(a));a->Print();delete a;return 0;
}

運行結果:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383827.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383827.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383827.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

處理大并發之二 對epoll的理解,epoll客戶端服務端代碼

http://blog.csdn.net/wzjking0929/article/details/51838370 序言&#xff1a; 該博客是一系列的博客&#xff0c;首先從最基礎的epoll說起&#xff0c;然后研究libevent源碼及使用方法&#xff0c;最后研究nginx和node.js&#xff0c;關于select,poll這里不做說明&#xff0c…

C++基類指針指向派生類(指針)

我們常用基類指針指向派生類對象來實現多態性。 私有繼承不允許基類指針指向派生類 基類指針只能訪問到基類中含有的公有成員。 當用基類指針指向派生類對象在動態分配堆上內存的時候&#xff0c;析構函數必須是虛函數! 成員如果是數據成員的話訪問的是基類的版本&#xff…

C++虛繼承中構造函數和析構函數順序問題以及原理

多重繼承的問題&#xff1a;多個類B,C,…繼承同一個類A導致如果X繼承了B,C,…那么在X中將還有多個A中成員的拷貝&#xff0c;如果想要訪問A中的成員如果不加名字空間將會導致二義性&#xff0c;這種拷貝大多是沒有實際意義的&#xff0c;為了避免這種空間浪費&#xff0c;C有虛…

一個簡單的linux線程池

http://blog.csdn.net/wzjking0929/article/details/20312675 線程池&#xff1a;簡單地說&#xff0c;線程池 就是預先創建好一批線程&#xff0c;方便、快速地處理收到的業務。比起傳統的到來一個任務&#xff0c;即時創建一個線程來處理&#xff0c;節省了線程的創建和回收的…

【C++學習筆記三】C++多態、抽象(接口)

當類之間存在多種層次結構&#xff0c;并且類之間通過繼承關聯時就會用到多態。 虛函數在子類中的覆蓋版本和該函數在基類中的原始版本必須有相同的函數簽名、函數名、形參名、常屬性。如果返回值為非類類型&#xff0c;則必須相同&#xff0c;如果是類類型A的指針或者引用&am…

C++重載和重寫的條件以及重寫后對基類函數的覆蓋

重載&#xff1a;同一個類中名字相同&#xff0c;參數列表不同的方法構成重載函數&#xff0c;和返回值沒有關系。這就意味著就算返回值不同&#xff0c;只要名字相同參數列表相同編譯器還是會報錯&#xff0c;覺得一函數被定義了兩次。 重寫&#xff1a;派生類中只要函數名字…

C++靜態成員和靜態方法

在類中&#xff0c;靜態成員可以實現多個對象之間共享數據&#xff0c;同時保證了安全性。靜態數據對該類的所有對象是公有的&#xff0c;存儲一處供所有對象使用。 注意&#xff1a; 靜態成員定義時需要在前面加上關鍵字static靜態成員必須初始化且必須在類外進行&#xff0…

基于epoll的簡單的http服務器

http://blog.csdn.net/fangjian1204/article/details/34415651 http服務器已經可以處理并發連接&#xff0c;支持多個客戶端并發訪問&#xff0c;每個連接可以持續讀寫數據&#xff0c;當然&#xff0c;這只是一個簡單的學習例子&#xff0c;還有很多bug&#xff0c;發表出來只…

C++單例模式簡單實現

有時候我們需要某個類只能被實例化一次&#xff0c;并且其他類都可以訪問到這個類&#xff0c;就需要這種設計模式。 例如我們想要做個資源管理器&#xff0c;顯然這個管理器只能有一個。 這種模式有很多實現方式&#xff0c;這里介紹最簡單的一種&#xff0c;想要了解更多可…

Linux C++ 實現線程池

http://blog.csdn.net/qq_25425023/article/details/53914609 線程池中的線程&#xff0c;在任務隊列為空的時候&#xff0c;等待任務的到來&#xff0c;任務隊列中有任務時&#xff0c;則依次獲取任務來執行&#xff0c;任務隊列需要同步。 Linux線程同步有多種方法&#xff…

C++制表符

制表符的轉義字符為\t&#xff0c;一般情況下長度為8個空格&#xff0c;這里的8個指的是從上一個字符串的開頭開始算&#xff0c;往后數8個&#xff0c;不夠的話就補空格。 如果前面的字符串的長度大于等于8個&#xff0c;例如前面字符串的長度為x,那么就會補(8-x%8)個空格 例…

C++派生類含有成員對象構造函數析構函數順序

參考博客&#xff1a;傳送門1 當類中含有對象成員時&#xff1a; 類的構造函數要包含對成員對象的初始化&#xff0c;如果構造函數的成員初始化列表沒有包含對成員對象的初始化&#xff0c;系統會自動調用成員對象的無參構造函數。順序上&#xff1a;先調用成員對象的構造函數…

c,c++中字符串處理函數strtok,strstr,strchr,strsub

http://blog.csdn.net/wangqing_12345/article/details/51760220 1&#xff0c;字符串切割函數 函數原型&#xff1a;char *strtok(char *s, char *delim); 函數功能&#xff1a;把字符串s按照字符串delim進行分割&#xff0c;然后返回分割的結果。 函數使用說&#xff1a; 1…

C++虛基類成員可見性

詳見《CPrimer》[第五版]719頁 如果繼承路徑上沒有和虛基類成員重名的成員&#xff0c;則不存在二義性&#xff0c;因為我們僅能訪問到虛基類成員。 當訪問僅有一條繼承路徑上含有和虛基類成員重名的成員&#xff0c;也不存在二義性。派生類的成員的優先級比基類的成員高&…

鏈表逆序的原理及實例

http://blog.csdn.net/wangqing_12345/article/details/51757294 尾插法建立鏈表&#xff0c;帶頭結點設鏈表節點為typedef struct node {int data;struct node *next;}node_t, *pnode_t;要求將一帶鏈表頭List head的單向鏈表逆序。 分析&#xff1a; 1). 若鏈表為空或只有一個…

C++關于虛基類、構造函數、析構函數、成員對象的兩個程序淺析

預備博客&#xff1a; C虛繼承中構造函數和析構函數順序問題以及原理 C派生類含有成員對象構造函數析構函數順序 C虛基類成員可見性 程序一如下&#xff1a; #include<iostream> using namespace std; class A { public:A(int a) :x(a) { cout << "A const…

strtok函數及其實現

頭文件&#xff1a;#include <string.h> 定義函數&#xff1a;char * strtok(char *s, const char *delim); 函數說明&#xff1a;strtok()用來將字符串分割成一個個片段。參數s 指向欲分割的字符串&#xff0c;參數delim 則為分割字符串&#xff0c;當 strtok()在參數s …

C++小型公司管理系統

項目要求&#xff1a; 編寫一個程序實現小型公司的人員信息管理系統。該公司雇員&#xff08;employee&#xff09;包括經理&#xff08;manager&#xff09;&#xff0c;技術人員&#xff08;technician&#xff09;、銷售員&#xff08;salesman&#xff09;和銷售部經理&…

Linux網絡編程“驚群”問題總結

http://www.cnblogs.com/Anker/p/7071849.html 1、前言 我從事Linux系統下網絡開發將近4年了&#xff0c;經常還是遇到一些問題&#xff0c;只是知其然而不知其所以然&#xff0c;有時候和其他人交流&#xff0c;搞得非常尷尬。如今計算機都是多核了&#xff0c;網絡編程框架也…

【Java學習筆記六】常用數據對象之String

字符串 在Java中系統定義了兩種類型的字符串類&#xff1a;String和StringBuffer String類對象的值和長度都不能改變&#xff0c;稱為常量字符串類&#xff0c;其中每個值稱為常量字符串。 StringBuffer類對象的值和長度都可以改變&#xff0c;稱為變量字符串類&#xff0c;其…