首頁 > 軟體

C++繼承詳細介紹

2022-10-20 14:03:35

前言

可能會涉及到組合的知識,不過這沒有關係,肯定能看懂,看不懂留言,我再做解釋。

使用到的工具是vs2010。

本節只講繼承的特點,公有私有多型等內容暫且不講,以後會細說。

一、什麼是繼承

繼承就是資料的複製

概念模糊、直接上程式碼:

#include <stdio.h>
#include <Windows.h>
struct Master            // 父類別(基礎類別)
{
	int a;
	int b;
};
struct Slave:Master      // 子類(派生類)
{
	int c;
	int d;
};
int main()
{
	Slave slave;
	slave.a = 1;
	slave.b = 2;
	slave.c = 3;
	slave.d = 4;
	int x = sizeof(slave);
	system("pause");      // 此處下斷點檢視x的大小(子類的大小)
	return 0;
}

執行,檢視x的值:

16,這足以說明slave是拷貝了一份a和b給slave子類的。

檢視組合:

可以看出繼承就是資料的複製

二、派生類和基礎類別的成員重複問題

1、派生類和基礎類別的成員可以重複嗎?

2、重複的話是使用的哪一個類的成員呢?

解答如下:

1、派生類和基礎類別的成員可以重複嗎?

可以。

證明:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	int a;
	int b;
};
struct Slave:Master
{
	int a;
	int d;
};
int main()
{
	Slave slave;
    printf("%d n",sizeof(slave));
	system("pause");           
	return 0;
}

執行:

不僅可以,而且slave類的大小依舊是16位元組;

這說明了子類的a和父類別的a是分開的,父類別的a依舊被拷貝到了子類,儘管子類已經有成員a;

2、重複的話是使用的哪一個類的成員呢?

這樣就不要使用變數來測試了,因為變數無法輸出內容,很難分辨出是父類別還是子類的,所以我們使用函數。

如下:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	void test()
	{
		printf("這是父類別的測試。n");
	}
};
struct Slave:Master
{
	void test()
	{
		printf("這是子類的測試。n");
	}
};
int main()
{
	Slave slave;
	slave.test();
	system("pause");
	return 0;
}

定義一父一子,類中都定義了test函數,那麼子類的物件會呼叫誰的呢?

執行如下:

子類呼叫了子類的。

父類別的物件會呼叫誰的呢?

測試如下:

執行:

父類別呼叫父類別。

可以看到,物件的預設呼叫都是本類自己定義的函數。

父類別呼叫子類方法

父類別可以呼叫子類方法嗎?如何呼叫?子類又如何呼叫父類別呢?

父類別可以呼叫子類方法,步過需要一些手段;子類可以直接呼叫父類別

先看一張圖:

從這張圖我們可以得知,子類包含了父類別中允許繼承的所有內容;但父類別不包含任何子類的東西。

所以,子類可以直接呼叫父類別是應該的,如下:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	void test()
	{
		printf("這是父類別的測試。n");
	}
};
struct Slave:Master
{
	void test()
	{
		printf("這是子類的測試。n");
	}
};
int main()
{
	Slave slave;
	slave.test();
	slave.Master::test();        // 宣告呼叫父類別的內容即可
	system("pause");
	return 0;
}

執行如下:

可以看到,子類正常的呼叫了父類別的方法;

如果父類別直接呼叫子類的呢?

如下:

直接呼叫的話是不被允許的。

不過可以通過其他方法進行呼叫;

父類別呼叫子類

我們知道,純虛擬函式是必須要子類進行實現的,如果父類別定義了純虛擬函式,子類不進行實現,就會報錯;我們可以通過這一點,讓父類別定義純虛擬函式,子類來實現這個純虛擬函式;然後父類別定義指標(純虛類就是介面類,無法定義物件,可以定義指標)來指向子類,呼叫子類的函數。

如下:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	virtual void test() = 0;		 // 父類別定義純虛擬函式
};
struct Slave:Master
{
	void test()						 // 子類實現純虛擬函式
	{
		printf("這是子類的測試。n");
	}
};
int main()
{
	Slave slave;
	slave.test();					 // 子類正常呼叫
	// Master master;				 // 不可以定義物件,會出錯。
	Master *master = &slave;		 // 可以定義指標指向子類
	master->test();
	system("pause");
	return 0;
}

執行:

成功呼叫。

當然還有其他方法可以讓父類別呼叫子類,不過本文章只講繼承,不深入其他內容;大家感興趣的話可以自己百度看看。

三、繼承不僅僅侷限於父類別

怎麼理解這個標題呢?就是說,不單單是父類別可以有派生類,子類也可以有派生類。

如果子類有派生類,那麼子類的派生類僅僅有父類別的成員,還是既有父類別的成員也有父類別的父類別成員?

觀點:子類的派生類,即會擁有父類別的公有成員也會擁有父類別的父類別的公有成員。

文字模糊,看圖:

通過這張圖我們可以知道:Son呼叫Slave的函數或者Master的函數可以直接呼叫;

Son包含Master和Slave所有公有成員、Slave只包含Master的公有成員、Master只包含自己的成員。

論證如下:

直接測試類所佔用位元組數就行了,如下:

#include <stdio.h>
#include <Windows.h>
struct Master
{
	int a;
	int b;
};
struct Slave:Master
{
	int c;
	int d;
};
struct Son:Slave
{
	int e;
	int f;
};
int main()
{
	int MasterSize = sizeof(struct Master);
	int SlaveSize = sizeof(struct Slave);
	int SonSize = sizeof(struct Son);
	printf("Master成員個數:t%dnSlave成員個數:tt%dnSon成員個數:tt%dn",MasterSize/4,SlaveSize/4,SonSize/4);
	system("pause");
	return 0;
}

Slave繼承Master,Son繼承Slave

三個類的成員都是int型別,所以通過類的位元組數/4就可以知道這個類有幾個成員

執行如下:

論證成功。

四、多重繼承

就是說子類不單單可以繼承一個父類別,可以繼承多個。

如下:

#include <stdio.h>
#include <Windows.h>
struct Master                 // 第一個父類別
{
	int a;
	int b;
};
struct Slave                  // 第二個父類別
{
	int c;
	int d;
};
struct Son:Slave,Master       // 兩個父類別
{
	int e;
	int f;
};
int main()
{
	int MasterSize = sizeof(struct Master);
	int SlaveSize = sizeof(struct Slave);
	int SonSize = sizeof(struct Son);
	printf("Master成員個數:t%dnSlave成員個數:tt%dnSon成員個數:tt%dn",MasterSize/4,SlaveSize/4,SonSize/4);
	system("pause");
	return 0;
}

執行如下:

所以,如圖:

這就是多重繼承,但是多重繼承增加了程式的複雜度,不建議使用 。

總結

1、什麼是繼承?

繼承就是資料的複製

2、為什麼要繼承?

減少重複程式碼的編寫

3、繼承不僅僅侷限於父類別

4、多重繼承增加了程式的複雜度,不建議使用

5、父類別基礎類別都是同一個東西,子類派生類都是同一個東西

到此這篇關於C++繼承詳細介紹的文章就介紹到這了,更多相關C++繼承內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com