1. 程式人生 > >C++ 類(多繼承和虛繼承)

C++ 類(多繼承和虛繼承)

文章概述

  1. 多繼承的定義以及多繼承的語法;
  2. 虛繼承;

多繼承的定義以及多繼承的語法

a. 一個類有多個基類,這樣的繼承關係稱為多繼承;
b. 多繼承宣告語法:

class 派生類名: 訪問控制符 基類名1,訪問控制符 基類名2
{
資料成員和成員函式宣告;
}

class A: public B,public c
{
}

圖示:
這裡寫圖片描述
c. 多個直接基類建構函式執行順序取決於定義派生類時指定的各個繼承基類的順序。

虛繼承

  1. 產生二義性 ?
class A
{
public:
    int x;
};

class B: public
A { int b; public: B(int x) { this->x = 10; } }; class C : public A { int c; public: C(int x) { this->x = 20; } }; class D :public B,public C { int d; public: D(int x):B(10),C(20) { //對於D中的x,到底是從哪個類(B,C)中繼承的,不明確,會產生二義性。 this
->x = 30; } };

對於產生二義性的原因分析在於分析d的物件模型:
這裡寫圖片描述
其實,產生二義性的原因就在於A的建構函式在c中呼叫了兩次,不知道x是哪個物件的。如果要讓A在c中只產生一個物件,則應該對公共基類A宣告為虛繼承,使得這個公共基類成為虛基類。
2. 在c中只產生一個公共基類的物件

//當類中出現virtual時,C++編譯器會物件新增一個vptr指標,同時會產生一個虛擬函式表
class A
{
public:
    int x;  //4
public:
    A()
    {
        cout << "A" << endl;
    }
};

class B:virtual
public A { int b; //4 public: B(int x) { this->x = 10; cout << "B" << endl; } }; class C :virtual public A { int c; //4 public: C(int x) { this->x = 20; cout << "C" << endl; } }; class D :public B,public C { int d; //4 public: D(int x):B(10),C(20) { this->x = 30; cout << "D" << endl; } }; int main() { cout << sizeof(A) << endl; //4 cout << sizeof(B) << endl; //12 cout << sizeof(C) << endl; //12 cout << sizeof(D) << endl; //24 return 0; }

分析d的物件模型:
這裡寫圖片描述
C++提供虛繼承機制,防止類繼承關係中成員訪問的二義性。

相關推薦

C++ (繼承繼承)

文章概述 多繼承的定義以及多繼承的語法; 虛繼承; 多繼承的定義以及多繼承的語法 a. 一個類有多個基類,這樣的繼承關係稱為多繼承; b. 多繼承宣告語法: class 派生類名: 訪問控制符 基類名1,訪問控制符 基類名2 {

C++ (繼承繼承)

文章概述       1. 多繼承的定義以及多繼承的語法;       2. 虛繼承; 多繼承的定義以及多繼承的語法 a. 一個類有多個基類,這樣的繼承關係稱為多繼承;  b. 多繼承宣告語法: class 派生類名: 訪問控制符 基類名1,訪問控制符 基類名2  { 

C++ 繼承繼承的記憶體佈局(Memory Layout for Multiple and Virtual Inheritance )

C++ 多繼承和虛繼承的記憶體佈局 在本文中,我們解釋由gcc編譯器實現多繼承和虛繼承的物件的佈局。雖然在理想的C++程式中不需要知道這些編譯器內部細節,但不幸的是多重繼承(特別是虛擬繼承)的實現方式有各種各樣的不太明確的結論(尤其是,關於向下轉型指標,使

47)繼承繼承

兩個 body name sleep pos out inf ima bsp 1)下面是一個多繼承的 代碼:      1 #include<iostream> 2 3 using namespace std; 4 class bed 5 {

C++ 多重繼承繼承 記憶體分佈

現在考慮一下怎麼去實現從top1到left的靜態轉換,同時要想到,我們並不知道top1是否指向一個Bottom型別的物件,或者是指向一個AnotherBottom型別的物件。所以這辦不到!這個重要的偏移依賴於top1執行時的型別(Bottom則20,AnotherBottom則24)。編譯器將報錯:

C++:虛擬函式繼承

1:虛解構函式主要是為了解決釋放父類的指標,同時釋放子類的指標,防止記憶體的洩露;例如 Father p = new Son();delete P;P= NULL;如果父類沒有解構函式則會造成記憶體洩露

鑽石繼承繼承

在C++中,類是允許多繼承的,多繼承大大的提高了程式碼的複用、減少程式碼冗餘、大大的提高了類的表現力,使得類更貼近現實中的事物,使用起來更為靈活,更面向物件。 但由於這靈活的語法,使得C++使用起來比

C++中虛擬函式工作原理 繼承的記憶體佔用大小計算

                      虛擬函式的實現要求物件攜帶額外的資訊,這些資訊用於在執行時確定該物件應該呼叫哪一個虛擬函式。典型情況下,這一資訊具有一種被稱為 vptr(virtual table pointer,虛擬函式表指標)的指標的形式。vptr 指向一個被稱為 vtbl(virtual t

C++在單繼承繼承繼承時,建構函式、複製建構函式、賦值操作符、解構函式的執行順序執行內容

一、本文目的與說明     1. 本文目的:理清在各種繼承時,建構函式、複製建構函式、賦值操作符、解構函式的執行順序和執行內容。     2. 說明:雖然複製建構函式屬於建構函式的一種,有共同的地方,但是也具有一定的特殊性,所以在總結它的性質時將它單獨列出來了。  

C++繼承;虛擬函式與繼承

定義:在C++中,在定義公共基類的派生類的時候,如果在繼承方式前使用關鍵字virtual對繼承方式限定,這樣的繼承方式就是虛擬繼承,公共的基類成為虛基類。這樣,在具有公共基類的、使用了虛擬繼承方式的多個派生類的公共派生類中,該基類的成員就只有一份拷貝

C++繼承匯總(單繼承繼承繼承、菱形繼承

虛基類表指針 www 地址 編譯 聲明 pre 繼承 第一個 src 一、C++中的對象模型 1、 概念 語言中直接支持面向對象程序設計的部分; 對於各種支持的底層實現機制。(沒看懂……) 2、 類中的成員分類 a) 成員函數   i. static function   

C++虛擬函式表在繼承繼承中的差別

下面的程式碼在gcc和VC中的結果 #include <cstdio> class A { public: virtual void funcaa() { printf("class A %s\n",__func__); } }; class AA:virtual pu

C++ 深入理解 繼承、多重繼承直接繼承

【摘要】 本文從5段程式碼例項出發,通過類中類的普通繼承,類的虛繼承,類的多重繼承,多個虛擬函式類的普通繼承、虛繼承與多重繼承,幾個交叉概念,詳細的闡釋了繼承、虛擬函式與虛繼承的基本概念,深入剖析了繼承於虛繼承的區別於聯絡。 【Exp.001-虛繼承】 #includ

c++虛擬函式繼承

1.多繼承可能會出現奇葩現象,多個同樣的變數,導致子類不知道呼叫的那個變數來自哪個父類。2.如果一個外部方法的引數是父類,那麼即使傳了一個子類,在方法中呼叫這個類的內部方法,不管你傳入的是子類還是父類,都會強行給你呼叫父類的方法。因為編譯器認為這樣是安全的,這個方法一定在父類

繼承繼承虛擬函式表對的大小的影響

一、真空類 class CNull { }; 長度:1 記憶體結構: ?? 評註:長度其實為0,這個位元組作為內容沒有意義,可能每次都不一樣。 二、空類 class CNull2 { public:     CNull2(){printf("Construct/

C++ 虛擬函式繼承解析

本文針對C++裡的虛擬函式,虛繼承表現和原理進行一些簡單分析,有不對的地方請指出。下面都是以VC2008編譯器對這兩種機制內部實現為例。 有喜歡或者想學習C/C++的朋友加一下我的C/C++交流群815393895。謝謝大家的支援 虛擬函式 以下是百度百科對於虛擬函式的

C++中的派生繼承

當類的繼承方式為私有繼承時,基類中的公有成員和保護成員都以私有成員身份出現在派生類中,而基類的私有成員在派生類中不可訪問。基類的公有成員和保護成員被繼承後作為派生類的私有成員,派生類的其他成員可以直接訪問它們,但是在類外部通過派生類的物件無法訪問。無論是派生類的成員還是通過派生類的物件,都無法訪問從基類繼承

C++虛擬函式及其繼承繼承大小

文章轉自: https://www.cnblogs.com/yanqi0124/p/3829964.html 一、虛擬函式與繼承 1、空類,空類單繼承,空類多繼承的sizeof #include <iostream> using namespace std

C++繼承繼承、虛擬函式的大小問題

一、真空類 class CNull { }; 長度:1 記憶體結構: ?? 評註:長度其實為0,這個位元組作為內容沒有意義,可能每次都不一樣。 二、空類 class CNull2 { public:     CNull2(){printf("Construct

鉆石(菱形)繼承

pan 由於 test 聲明 16px pri 技術分享 color protect 鉆石(菱形)繼承 如圖,B,C繼承了A,D繼承了B,C 在這種情況下,如果D類的對象通過B、C兩個不同的作用域調用A的數據成員,將會產生兩個 不同的A的數據成員值 如下(Grandfat