// 练习.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) { } }; 但要注意的是有虚基类后情况就又不同了,具体的还要调查.