1. 程式人生 > >C++物件在記憶體中的儲存

C++物件在記憶體中的儲存

最近忽然迷惑,子類繼承父類之後,子類物件在記憶體中的儲存方式是怎樣的。理論上上應該是虛擬函式表指標、父類變數、子類變數。父類變數儲存時是否和子類變數一起實現記憶體對齊呢?

為了搞明白這個問題,做了如下實驗。

編譯環境:win32,VS2008,Version3.5 SP1

#include "stdafx.h"
#include<iostream>

using namespace std;

class A
{
public:
A(char ch){m_a = ch;}
virtual void funcA(){cout<<"virtual funcA"<<endl;}
public:
char m_a;

};

class B:public A
{
public:
B(char ch):A('A')
{
m_b = ch;
m_b1 = ch;
}
virtual void  funcB(){cout<<"virtual funcB"<<endl;}
public:
char m_b;
char m_b1;
};


int _tmain(int argc, _TCHAR* argv[])
{
A a('A');
B b('B');
int aa = 0;
typedef void (*FUNCP)(void) ;
       FUNCP fpA = NULL, fpB = NULL;

int*p = NULL;
int *pp = NULL;
printf("sizeof(A) = %d\n",sizeof(a));// 8
printf("sizeof(B) = %d\n",sizeof(b));// 12


printf("address of a = %0x\n",(long)&a);   // 2dfb54
printf("address of a.m_a = %0x\n",(long)&a.m_a);// 2dfb58

printf("address of b = %0x\n",(long)&b);//2dfb40
printf("address of b.m_a = %0x\n",(long)&b.m_a);// 2dfb44
printf("address of b.m_b = %0x\n",(long)&b.m_b);// 2dfb48
printf("address of b.m_b1 = %0x\n",(long)&b.m_b1);// 2dfb49

p = (int *)(&b.m_a-4);
pp =(int *) *p;

fpA = (FUNCP)*pp;
fpA(); //virtual funcA

fpB = (FUNCP)*(pp+1);
fpB(); //virtual funcB

scanf("%d\n",&aa);
return 0;
}

從輸出結果來看,子類物件的確是按照虛擬函式表指標,父類變數,子類變數的順序儲存。

而且父類變數不跟子類變數一起參與記憶體對齊。

從類物件起始地址向後移動虛擬函式指標所佔記憶體大小之後,即可以訪問到類物件的資料,

無論此資料的屬性是公有還是私有或者保護型。這從一定意義上破壞了類的封裝性,但是雖然能夠訪問到資料,

卻不知道資料的型別。

相關推薦

jvm 物件記憶體儲存的佈局

jvm  物件在記憶體中儲存的佈局有三部分:物件頭、例項資料、對齊填充。 1、物件頭:執行時資料、型別指標、陣列長度。 (1)執行時資料:hashcode雜湊碼、鎖狀態標誌、執行緒持有的鎖、GC年齡分代等,有些不是固定不變的,在執行時會根據當時的狀態進行修改。 (2)型別指標:

C語言—記憶體的五大區域/CC++在記憶體儲存方式

簡單來說,C/C++在記憶體中的儲存佔用五個區域,分別是:棧區Stack、堆區Heap、BSS區、資料區(常量區)Data和程式碼區Text。其中,棧區由系統在編譯過程中自動分配;堆區在程式的執行過程中動態分配,由程式設計師控制堆區儲存的開闢和釋放;程式中的常量資料被分散在兩個區記憶體儲,一個是BSS區,儲存

C語言——printf列印字串(關於資料在記憶體儲存格式的體現)

PS:本篇文章,是筆者在C語言學習過程中的所產生疑惑的地方,經過查閱相關資料得出的結論,如有錯誤的地方,還望指出改正。 int 佔4個位元組, 這裡輸入的8位16進位制數每相鄰兩位數代表一個位元組。如:44,43,42,41 int b = 0x414

C++物件記憶體模型2 (虛擬函式,虛指標,虛擬函式表)

C++物件記憶體模型2 (虛擬函式,虛指標,虛擬函式表) 從例子入手,考察如下帶有虛擬函式的類的物件記憶體模型: class A { public: virtual void vfunc1(); virtual void vfunc2(); void func1();

C++物件模型的虛擬函式分析

對於虛擬函式,知道它的含義,也能夠描述出來。參照百度百科,也就是“它提供了‘動態繫結’機制”。 可總是感覺有些迷糊,於是敲了一段程式碼出來試驗,一探究竟(程式設計環境是VC6.0)。對比程式碼和結果,一切都不言自明。 現在把程式碼和結果貼上來,作為儲存記錄,同時也歡迎大家提出意見,以臻完善。

c++物件記憶體佈局模型

轉自:點選開啟連結 首先介紹一下C++中有繼承關係的類物件記憶體的佈局:  在C++中,如果類中有虛擬函式,那麼它就會有一個虛擬函式表的指標__vfptr,在類物件最開始的記憶體資料中。之後是類中的成員變數的記憶體資料。  對於子類,最開始的記憶體資料記錄著父類物件的拷貝

整形數int、浮點型資料float,在記憶體儲存的表示

引言: 突然想到一個底層問題。 計算機組成原理裡學的:定點整數 定點小數 浮點數; 程式設計裡的基本資料型別int float在記憶體中的儲存形式; 二者究竟的對應關係是? CSDN部落格裡有這樣一句話,“實數在記憶體中以規範化的浮點數存放”,請先理清“實數”是多大範圍再回味這句話! 我在書上看到

反彙編C++ OOP程式碼 分析建構函式如何被呼叫 以及簡單的C++物件記憶體模型

在今天進行C++程式碼的思考時,產生一個疑問,就是C++類的建構函式是如何被呼叫的 於是就做了一個簡單的實驗來驗證自己的想法。 //main.cpp #include &lt;stdio.h&gt; class People{ private: int i; i

牛客網——華為機試(題15:求int型正整數在記憶體儲存時1的個數)(Java)

題目描述: 輸入一個int型的正整數,計算出該int型資料在記憶體中儲存時1的個數。 輸入描述: 輸入一個整數(int型別) 輸出描述:  這個數轉換成2進位制後,輸出1的個數 示例1: 輸入: 5 輸出: 2 程式碼:  import java.ut

lua C++物件記憶體管理

1:tolua++如何管理物件的生命週期 一般情況下,當lua裡對c++物件的引用變數可以被垃圾回收時,tolua++只是簡單的釋放userdata佔用的4位元組指標地址記憶體。但是也可以通過繫結或者程式碼指定的方式,讓tolua++真正釋放物件所佔記憶體。 繫結的方

c++物件記憶體的分配

1 關於c++的物件 只要是用了class或者struct定義的,都是物件,不管有沒有方法。不過,一般情況下,沒有方法的物件用struct關鍵字來定義。 2 不用new關鍵字定義物件 要看這樣的物件在記憶體中的位置,要看它所處的上下文。 如果是在函式中,那麼這個物件的記憶體

C# DataSet(記憶體的資料集)

DataSet 中有多個 DataTable;DataTable 中有多個DataColumn (列名),多個Rows (資料行)。 using System; using System.Collections.Generic; using System.Component

java的各種資料型別在記憶體儲存的方式

1.java是如何管理記憶體的 java的記憶體管理就是物件的分配和釋放問題。(其中包括兩部分) 分配:記憶體的分配是由程式完成的,程式設計師需要通過關鍵字new為每個物件申請記憶體空間(基本型別除外),所有的物件都在堆(Heap)中分配空間。 釋放:物件的釋放是由

C++物件記憶體佈局

想要研究物件的記憶體佈局必須要去對應的記憶體去檢視。 一、兩種檢視物件記憶體的方法 先選擇我們寫的C++原始檔,右鍵選擇屬性,在彈出的對話方塊中選擇左側的C/C++->命令列,然後在其他選項這裡寫上/d1reportAllClassLayout,它可以看到所有相關類

華為oj 字串個數統計&&數字顛倒&&字串翻轉&&字元逆序&&求int型資料在記憶體儲存時1的個數

同樣只上程式,都是簡單題 #include<iostream> using namespace std; int main() { int in[128], count = 0; char n,temp[100]; memset(in, 0, sizeo

求int型資料在記憶體儲存時1的個數

題目描述輸入一個int型的正整數,計算出該int型資料在記憶體中儲存時1的個數。輸入描述: 輸入一個整數(int型別)輸出描述: 這個數轉換成2進位制後,輸出1的個數示例1輸入5 輸出2import j

字串記憶體儲存位置

原文連結:http://blog.csdn.net/yangdelong/article/details/5447362?reload ---------------------------------------------------------------------

C++物件記憶體儲存

最近忽然迷惑,子類繼承父類之後,子類物件在記憶體中的儲存方式是怎樣的。理論上上應該是虛擬函式表指標、父類變數、子類變數。父類變數儲存時是否和子類變數一起實現記憶體對齊呢? 為了搞明白這個問題,做了如下實驗。 編譯環境:win32,VS2008,Version3.5 SP1

C語言儲存類別、連結與記憶體管理

  第12章 儲存類別、連結和記憶體管理 通過記憶體管理系統指定變數的作用域和生命週期,實現對程式的控制。合理使用記憶體是程式設計的一個要點。 12.1 儲存類別 C提供了多種不同的模型和儲存類別,在記憶體中儲存資料。 被儲存的每一個值都佔用一定的實體記憶體;C語言把這樣一塊記憶體稱為物件

C語言的細節問題】C/C++浮點數在記憶體儲存方式

C/C++浮點數在記憶體中的儲存方式 本文轉載自:https://www.cnblogs.com/dolphin0520/archive/2011/10/02/2198280.html        任何資料在記憶體中都是以二進位制