- // 練習.cpp : 定義控制檯應用程序的入口點。
- #include "stdafx.h"
- #include <iostream>
- using namespace std;
- class A
- {
- public:
- A(){}
- A(int a):m_a(a){}
- virtual void print()
- {
- cout<<"A::"<<m_a<<endl;
- }
- private:
- int m_a;
- };
- class B:public virtual A
- {
- public:
- B(){}
- B(int a, int b):A(a),m_b(b){}
- virtual void print()
- {
- A::print();
- printf("B::%d/n", m_b);
- }
- private:
- int m_b;
- };
- int main()
- {
- cout<<sizeof(A)<<endl;
- cout<<sizeof(B)<<endl;//sizeof(B)=sizeof(A)+sizeof(m_b)+sizeof(指向B中虛函數print的指針)+sizeof(指向父類A的指針(虛繼承))
- }
- class demo
- {
- public:
- virtual void f(int){}
- virtual void f(double){}
- virtual void g(int){}
- };
- class Derived:public demo
- {
- virtual void g(int){}
- };
- cout<<sizeof(Derived)<<endl;
- 輸出結果爲4
- class demo
- {
- public:
- virtual void f(int){}
- virtual void f(double){}
- virtual void g(int){}
- };
- class Derived:public demo
- {
- virtual void gt(int){}
- };
- cout<<sizeof(Derived)<<endl;
- 輸出結果爲4
- class demo
- {
- public:
- virtual void f(int){}
- virtual void f(double){}
- virtual void g(int){}
- };
- class Derived:public virtual demo
- {
- virtual void g(int){}
- };
- cout<<sizeof(Derived)<<endl;
- 輸出結果爲8
- 此爲虛繼承,子類複製父類的所有內容,並定義一個指針指向複製過來的內容。函數g覆蓋掉虛表中的函數。
- class demo
- {
- public:
- virtual void f(int){}
- virtual void f(double){}
- virtual void g(int){}
- };
- class Derived:public virtual demo
- {
- virtual void gt(int){}
- };
- cout<<sizeof(Derived)<<endl;
- 輸出結果爲12
- 子類還要定義一個虛指針,指向自己的虛表,把函數gt插入虛表。
- 如果爲多繼承,則定義多個虛表。
- 1.常規
- char str1[] = “Hello” ;
- char str2[5] = {'H','e','l','l','o'};
- char str3[6] = {'H','e','l','l','o','/0'};
- char *p1 = "Hello";
- char *p2[]={"hello","world"};
- int n = 10;
- int *q = &n;
- sizeof (str1 ) = 6 (自動加了'/0')
- strlen (str1 ) = 5 (字符串的長度)
- sizeof (str2 ) = 5 (字符數組的大小)
- strlen (str2) = 未知 (該字符串缺少結束符'/0')
- sizeof (str3) = 6 (字符數組的大小)
- strlen (str3) = 5 (該字符串的長度爲5)
- sizeof ( p1 ) = 4 (p1是一個指針,大小爲4)
- sizeof ( p2 ) = 8 (p2是長度爲2的字符串數組)
- sizeof ( n ) = 4 (整型大小爲4)
- sizeof ( q ) = 4 (q是一個指針,大小爲4)
- 2.動態分配內存
- int *p = (int *)malloc( 100 );
- sizeof ( p ) = 4 (p是一個指針,大小爲4)
- 3.函數參數
- void Function1( char p[],int num ){
- sizeof ( p ) = 4 (數組在做爲函數參數時均化爲指針)
- }
- void Function2( int p[],int num ){
- sizeof ( p ) = 4 (數組在做爲函數參數時均化爲指針)
- }
- 4.多重繼承
- class A{};
- class B{};
- class C:public A,public B{};
- class D:virtual public A{};
- class E:virtual public A,virtual public B{};
- sizeof ( A ) = 1 (空類大小爲1,編譯器安插一個char給空類,用來標記它的每一個對象)
- sizeof ( B ) = 1 (空類大小爲1,編譯器安插一個char給空類,用來標記它的每一個對象)
- sizeof ( C ) = 1 (繼承或多重繼承後空類大小還是1)
- sizeof ( D ) = 4 (虛繼承時編譯器爲該類安插一個指向父類的指針,指針大小爲4)
- sizeof ( E ) = 8 (指向父類A的指針與父類B的指針,加起來大小爲8)
- 5.數據對齊
- 類(或結構)的大小必需爲類中最大數據類型的整數倍.CPU訪問對齊的數據的效率是最高的,因此通常編譯浪費一些空間來使得我們的數據是對齊的
- class A{
- public:
- int a;
- };
- class B{
- public:
- int a ;
- char b;
- };
- class C{
- public:
- int a ;
- char b;
- char c;
- };
- sizeof(A) = 4 (內含一個int ,所以大小爲4)
- sizeof(B) = 8 (int爲4,char爲1,和爲5,考慮到對齊,總大小爲int的整數倍即8)
- sizeof(C) = 8 (同上)
- 6.函數與虛函數
- 編譯器爲每個有虛函數的類都建立一個虛函數表(其大小不計算在類中),併爲這個類安插一個指向虛函數表的指針,即每個有虛函數的類其大小至少爲一個指針的大小4
- class A{
- public:
- int a;
- void Function();
- };
- class B{
- public:
- int a;
- virtual void Function();
- };
- class C:public B{
- public:
- char b;
- };
- class D:public B{
- public:
- virtual void Function2();
- };
- class E{
- public:
- static void Function();
- };
- sizeof (A) = 4 (內含一個int,普通函數不佔大小)
- sizeof (B) = 8 (一個int ,一個虛函數表指針)
- sizeof (C) =12 (一個int ,一個虛函數表指針,一個char ,再加上數據對齊)
- sizeof (D) = 8 (一個int ,一個虛函數表指針,多個虛函數是放在一個表裏的,所以虛函數表指針只要一個就行了)
- sizeof (E) = 1 (static 函數不佔大小,空類大小爲1)
- 7.父類的私有數據
- 雖然在子類中不可用,但是是可見的,因此私有的數據還是要佔子類的大小
- class A{
- private:
- int a;
- };
- class B:public A{};
- sizof(B) = 4; (內含一個不可用的父類的int)
- 8.大概就這麼多了吧,想到再加吧。虛函數,多重繼承,空類是比較複雜的,大家大概記住知道就行了
- weiloujushi補充:
- class static_D
- {
- int static intVar;
- static void fun(){}
- };
- sizeof(static_D) ==1 //靜態數據成員不計入類內
- 我們用sizeof測一個類所佔內存空間的大小時,會得到什麼結果,虛函數表有什麼影響?
- 如果一個類裏面什麼也不實現,只實現一個或多個虛函數的話,測它的sizeof會得到4,但如果一個類從多個類繼承,並且它的多個基類有虛函數的話,它就會有多個虛函數表了,這個在COM也有體現.如下例
- class A
- {
- public:
- virtual void PrintA1(void)
- {
- }
- virtual void PrintA2(void)
- {
- }
- };
- class B
- {
- public:
- virtual void PrintB(void)
- {
- }
- };
- class C
- {
- public:
- virtual void PrintC(void)
- {
- }
- };
- class D : public A, public B, public C
- {
- };
- 測試結果是
- sizeof(D) = 12;
- 如果D類改成下面的樣子,即在它裏面再加一個虛函數,結果還是12
- class D : public A, public B, public C
- {
- public:
- virtual void PrintD(void)
- {
- }
- };
- 但要注意的是有虛基類後情況就又不同了,具體的還要調查.