1. 程式人生 > >C++ 繼承的 虛基表記憶體模型,看了下 寫的不錯

C++ 繼承的 虛基表記憶體模型,看了下 寫的不錯



c++中一個類中無非有四種成員:靜態資料成員和非靜態資料成員,靜態函式和非靜態函式。

    1.非靜態資料成員被放在每一個物件體內作為物件專有的資料成員。
    2.靜態資料成員被提取出來放在程式的靜態資料區內,為該類所有物件共享,因此只存在一份。
    3.靜態和非靜態成員函式最終都被提取出來放在程式的程式碼段中併為該類所有物件共享,因此每一個成員函式也只能存在一份程式碼實體。在c++中類的成員函式都是儲存在靜態儲存區中的,那靜態函式也是儲存在靜態儲存區中的,他們都是在類中儲存同一個憊份。
    因此,構成物件本身的只有資料,任何成員函式都不隸屬於任何一個物件,非靜態成員函式與物件的關係就是繫結,繫結的中介就是this指標

。成員函式為該類所有物件共享,不僅是處於簡化語言實現、節省儲存的目的,而且是為了使同類物件有一致的行為。同類物件的行為雖然一致,但是操作不同的資料成員。

#include"iostream.h"

class A
{
private:
 int x;
 int y;
public:
 void sety()
 {
  y=5;
 }
 void print()
 {
  cout<<"x="<<x<<endl<<"y="<<y<<endl;
 }
};

void main()
{
  A a;
  a.sety();
  a.print();
 int *p=(int *)&a;//物件a的記憶體模型裡面,只有非靜態資料成員,所以是合理的。

  *p=6;
  a.print();
}

    4.單繼承的物件的記憶體佈局,第一個為函式指標vtbl,其後為成員且先基類後子類,虛擬函式表裡包含了所有的虛擬函式的地址,以NULL結束。虛擬函式如果子類有重寫,就由子類的重新的代替

                              C++物件的記憶體分佈和虛擬函式表

   <一>上述類圖的解釋:B的v2覆蓋了A的v2,C的v1覆蓋了A的v1,C的v3覆蓋了B的v3.

    注意:發生覆蓋的特徵有:

1) 不同的範圍(分別位於派生類與基類);

    2) 函式名字相同

    3) 引數相同

    4) 基類函式必須有virtual關鍵字

。 

成員函式被過載的特徵
  (1)相同的範圍(在同一個類中);
  (2)函式名字相同;
  (3)引數不同;
  (4)virtual 關鍵字可有可無
  “隱藏”是指派生類的函式遮蔽了與其同名的基類函式,規則如下
  (1)如果派生類的函式與基類的函式同名,但是引數不同。此時,不論有無virtual關鍵字,基類的函式將被隱藏(注意別與過載混淆)。
  (2)如果派生類的函式與基類的函式同名,並且引數也相同,但是基類函式沒有virtual 關鍵字。此時,基類的函式被隱藏(注意別與覆蓋混淆)   

<二>類C的物件的記憶體模型為:

   C++物件的記憶體分佈和虛擬函式表
    單繼承的物件的佈局,第一個為虛函式表指標vtbl,其後為成員且先基類後子類,虛擬函式表裡包含了所有的虛擬函式的地址,以NULL結束。虛擬函式如果子類有重寫,就由子類的重新的代替。
    5.與單繼承相同的是所有的虛擬函式都包含在虛擬函式表中,所不同的多重繼承有多個虛擬函式表,當子類對父類的虛擬函式有重寫時,子類的函式替換父類的函式在對應的虛擬函式位置,當子類有新的虛擬函式時,這些虛擬函式被加在第一個虛擬函式表的後面

                     C++物件的記憶體分佈和虛擬函式表

<一>對類圖的解釋:D的v3覆蓋了B3的v3,另外D有一個新的虛擬函式vD。

<二>class D 的記憶體模型

           C++物件的記憶體分佈和虛擬函式表 
    總結:與單繼承相同的是所有的虛函式都包含在虛擬函式表中,所不同的多重繼承有多個虛擬函式表,當子類對父類的虛擬函式有重寫時,子類的函式覆蓋父類的函式在對應的虛擬函式位置,當子類有新的虛擬函式時,這些虛擬函式被加在第一個虛擬函式表的後面

     6.虛繼承,使公共的基類在子類中只有一份,我們看到虛繼承在多重繼承的基礎上多了vbtable來儲存到公共基類的偏移。

                      C++物件的記憶體分佈和虛擬函式表

<一>類圖的解釋:D2覆蓋了B的vB,GD覆蓋了D1的vD1同時也覆蓋B的vB,GD也有自己的虛擬函式vGD。

<二> class GD的記憶體模型

           C++物件的記憶體分佈和虛擬函式表
    總結:虛繼承,使公共的基類在子類中只有一份,我們看到虛繼承在多重繼承的基礎上多了vbtable來儲存到公共基類的偏移

相關推薦

C++ 繼承記憶體模型 不錯

 c++中一個類中無非有四種成員:靜態資料成員和非靜態資料成員,靜態函式和非靜態函式。     1.非靜態資料成員被放在每一個物件體內作為物件專有的資料成員。     2.靜態資料成員被提取出來放在程式的靜態資料區內,為該類所有物件共享,因此只存在一份。     3.靜

C++繼承時的物件記憶體模型

推薦閱讀:http://blog.csdn.net/randyjiawenjie/article/details/6693337           最近研究了一下,C++繼承的記憶體物件模型。主要是讀了讀http://blog.

C/C++編譯器教程之如何安裝vs的人應該都會裝只要不手殘

什麽 dia color tps image spa pad 開始 有一個 這很簡單,其實我覺得不用教,但是吧,你們總有很多問題,所以,就有了這個安裝教程。以上是廢話。首先下載vs編譯器得相關文件就是這兩個文件,上面的txt和下面的iso文件對的,先下載,然後,下載完成之

繼承裡既有繼承也有虛擬函式繼承(即既有也有虛擬函式

對於單一的虛繼承可參考這篇部落格: https://blog.csdn.net/sophia__yu/article/details/82791522 對於有虛擬函式繼承可參考這篇部落格: https://blog.csdn.net/sophia__yu/article/details/82

c++記憶體模型變數和函式

1、c++中方法 儲存在單獨的方法表中,fuction——table,類中有方法指標來指向方法表中方法的實際地址,static和nonstatic 方法都儲存在方法表中。 2、c++中類的物件的 成員變數存在class中,static 變數儲存在class之外。 3、c++的成員指標式類似slot 插槽式設

C++ 多重繼承

使用多個基類的繼承被稱為多重繼承(MI)。 MI描述的是有多個直接基類的類。與單繼承一樣,公有MI表示的也是 is--a關係。 MI帶來的兩個主要問題: 1. 從兩個不同的基類繼承同名方法。 2. 從兩個或更多相關基類那裡繼承同一類的多個例項。 例如: s

C語言》單鏈——記憶體管理

《C語言》單鏈表——記憶體管理 Main.c MemManage.h MemManage.c Main.c #define SAFE_MEMORY #include "MemManage.h" #include <time.h&

Java記憶體模型是什麼為什麼要有Java記憶體模型Java記憶體模型解決什麼問題?

網上有很多關於 Java 記憶體模型的文章,但是很多人讀完之後還是搞不清楚,甚至有的人說自己更懵了。 本文就來整體的介紹一下 Java 記憶體模型,讀完本文以後,你就知道到底 Java 記憶體模型是什麼,為什麼要有 Java 記憶體模型,Java 記憶體模型解決了什麼問

Java記憶體模型是什麼為什麼要有Java記憶體模型Java記憶體模型解決什麼問題等。。。

本文中,有很多定義和說法,都是筆者自己理解後定義出來的。希望能夠讓讀者可以對Java記憶體模型有更加清晰的認識。當然,如有偏頗,歡迎指正。 為什麼要有記憶體模型 在介紹Java記憶體模型之前,先來看一下到底什麼是計算機記憶體模型,然後再來看Java記憶體模型在

Java 高併發第二階段實戰---高併發設計模式記憶體模型CPU一致性協議volatile關鍵字剖析

汪文君高併發程式設計第二階段01講-課程大綱及主要內容介紹. 汪文君高併發程式設計第二階段02講-介紹四種Singleton方式的優缺點在多執行緒情況下. 汪文君高併發程式設計第二階段03講-介紹三種高效優雅的Singleton實現方式. 汪文君高併發程式設計第二階段04講-多執行緒的休息室WaitSet詳細

C++例項---類的建構函式和初始化

執行環境:macOS shell 程式碼: #include <iostream> #include <iomanip> #include <string> using namespace std; class base

C++面試常見題目4_記憶體管理記憶體洩露

記憶體管理 定義:記憶體管理是指軟體執行時對計算機記憶體資源的分配和使用的技術。其最主要的目的是如何高效,快速的分配,並且在適當的時候釋放和回收記憶體資源。 在C++中記憶體分為5個區,分別是堆、棧、自由儲存區、全域性/靜態儲存區和常量儲存區。 堆:堆是

JVM記憶體模型以及JVM效能調優

轉載批註:最近因與別人討論問題時,問到JVM記憶體模型,但是苦於只知道JVM的大概內容,不知道詳細,也罷,近期會逐漸有充足的自己的時間,好好整理學習學習。以下內容為轉載別人的資料,個人認為寫的很好,就全文拷貝了。 ===================華麗的分割線==

C++-繼承類與派生類的關係

成員函式的重定義和名字隱藏 基類的資料成員和成員函式在派生類中都有一份拷貝,派生類能夠直接訪問從基類繼承而來的public和protected成員,且只能夠通過這兩類成員訪問從基類繼承而來的private成員。 派生類不僅可以新增基類沒有的新成員,而且可以對

jvm的stack和heapJVM記憶體模型垃圾回收策略分代收集增量收集(轉)

在JVM中,記憶體分為兩個部分,Stack(棧)和Heap(堆),這裡,我們從JVM的記憶體管理原理的角度來認識Stack和Heap,並通過這些原理認清Java中靜態方法和靜態屬性的問題。   一般,JVM的記憶體分為兩部分:Stack和Heap。   Stack(棧)是JVM的記憶體指令區。Sta

asp.net(C#)的九九乘法有問題

 用asp.net(c#)寫的九九乘法表,要求輸入開始值和結束值,我寫的程式程式碼如下: using System;using System.Data;using System.Configuration;using System.Web;using System.Web.S

【JVM】上帝視角JVM記憶體模型分而治之論各模組詳情

1. 上帝視角【樹看JVM】【圖看JVM】2. 分而治之 2.1 堆區    構成:堆區由新生代和老年代組成,新生代中包含伊甸區(Eden)、倖存者區(survivor from 、survivor to)和老年代。    GC:當建立新的物件時,物件首先會被放入Eden和s

QT 新增C++類C++類嚮導類選擇時無“QDialog;選項

1.軟體環境:  版本:5.6.1  作業系統:win10家庭版64位  MSVC版本:2013(32bit)2.問題描述:C++類嚮導基類選擇時,無“QDialog&quot;選項      

JVM(二)---記憶體模型可見性指令重排序

1.記憶體模型 收修庵我們思考一下java執行緒要向另一個執行緒進行通訊,應該怎麼做,我們再把需求明確一點,一個java執行緒對一個變數的更新怎麼通知到另外一個執行緒呢?我們知道java的例項物件、陣列元素都存放在java堆中,java堆是執行緒共享

硬體記憶體模型到 Java 記憶體模型這些硬核知識你知多少?

Java 記憶體模型跟上一篇 JVM 記憶體結構很像,我經常會把他們搞混,但其實它們不是一回事,而且相差還很大的,希望你沒它們搞混,特別是在面試的時候,搞混了的話就會答非所問,影響你的面試成績,當然也許你碰到了半吊子面試官,那就要恭喜你了。Java 記憶體模型比 JVM 記憶體結構複雜很多,Java 記憶體模