如何理解虚表及其计算含虚函数的类的大小

在什么情况下系统会自动生成缺省(默认)的构造函数?

1、在类里面有一个类类型的对象,这个类有自己的缺省构造函数(有缺省的参数,参数有缺省值)。

class B

{

B(int data)

{  }

};不能合成

class B

{

B(int data=0)

{  }

};会合成

class B

{

public:

B(int data=0)

{  }

};

class C:public B

{

public:

C()

:B(0)

{  }

B b;  //编译器会自动合成

};

2、类是虚拟继承

class B

{

public:

B()

{}

};

class D:virtual public B

{

public:

D()

{ }

B b;

};

3、基类有缺省构造函数,子类没有显示定义自己的构造函数

class B

{

public:

B(int data=0)

{}

};

class D: public B

{

public:

};

4、有虚函数的类,系统自动生成缺省的构造函数来初始化虚指针

class B

{

public:

virtual  void fun()

{

cout << "fun" << endl;

}

};

前面是一些构造函数方面的总结,菜鸟一个写的太烂,进来的先凑合着看,会不定时补充,有错误的地方还请多多指点

****************************************************************************************

虚函数:

class Base

{

public:

virtual void FunTest()

{

cout << "Base::FunTest()" << endl;

}

virtual void FunTest1()

{

cout << "Base::FunTest1()" << endl;

}

virtual void FunTest2()

{

cout << "Base::FunTest2()" << endl;

}

virtual void FunTest3()

{

cout << "Base::FunTest3()" << endl;

}

virtual void FunTest4()

{

cout << "Base::FunTest4()" << endl;

}

};

int main()

{

Base b;

system("pause");

return 0;

}

Base b;

009253E8  lea         ecx,[b]

009253EB  call        Base::Base (0921226h)

有call命令说明编译器有合成缺省构造函数

取b的地址,b指向的那块空间里存放着另一个地址,该地址指向的空间存放着虚表地址

虚指针指向虚表

虚表的顺序和函数的声明顺序是一样的

虚函数的大小:

***************************计算大小*********************************

class C

{

public:

char a;  //1

static char b;  //静态成员在静态区域,不在栈区,所以不算

void *p;    //指针占4个字节

static int *c;   //静态成员在静态区域,不在栈区,所以不算

virtual void func1()

{}

virtual void func2()

{}

//虚函数属于同一类,故只需要一个这个指针指向虚函数表,

//占用4个字节,就算有N个虚函数,也是4个字节

};

int main()

{

C c;

cout << sizeof(C) << endl;    //12

cout << sizeof(c.a) << endl;    //1

cout << sizeof(c.b) << endl;   //1    类型的大小

cout << sizeof(c.c) << endl;    //4     类型的大小

cout << sizeof(c.p) << endl;    //4

return 0;

}

时间: 2024-11-07 07:16:51

如何理解虚表及其计算含虚函数的类的大小的相关文章

含有虚函数的类sizeof大小

#include <iostream> using namespace std; class Base1{ virtual void fun1(){} virtual void fun11(){} public: virtual ~Base1(); }; class Base2{ virtual void fun2(){} }; class DerivedFromOne: public Base2 { virtual void fun2(){} virtual void fun22(){} }

空类,含有虚函数的类的大小

1.为何空类的大小不是0呢? 为了确保两个不同对象的地址不同,必须如此. 类的实例化是在内存中分配一块地址,每个实例都有独一无二的内存地址.空类也会实例化,为保证空类实例化后的独一无二性,编译器会给空类隐含的添加一个字节.所以,空类的sizeof为1,而不是0. 2.继承关系中的类大小: case 1: 父类有虚函数,子类继承. class A{ virtual void f(){} }; class B:public A{} 此时,类A和类B都不是空类,其sizeof都是4,因为它们都具有虚函

用含成员函数的类来实现输入和输出时间

用含成员函数的类来实现输入和输出时间. 程序: #include<iostream> using namespace std; class Time { public: void set_time(); void show_time(); private: int hour; int minute; int sec; }; int main() { Time t1; t1.set_time(); t1.show_time(); Time t2; t2.set_time(); t2.show_t

构造函数为什么不能为虚函数 &amp; 基类的析构函数为什么要为虚函数

一.构造函数为什么不能为虚函数 1. 从存储空间角度,虚函数对应一个指向vtable虚函数表的指针,这大家都知道,可是这个指向vtable的指针其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢?所以构造函数不能是虚函数. 2. 从使用角度,虚函数主要用于在信息不全的情况下,能使重载的函数得到对应的调用.构造函数本身就是要初始化实例,那使用虚函数也没有实际意义呀.所以构造函数没有必要是虚函

关于虚函数,类的内存分布以及类的成员函数调用原理

1.类的内存分布 空类为了占位,空间占一个字节 成员函数,静态函数,静态变量并不占内存(不和类放在一起) 所有的虚函数也并不和类放在一起,而是将所有的虚函数构造成一个虚函数表,用一个指针指向这个虚函数表,类仅仅存储这个指针,一个指针在32位的机器上占四个字节 所有的非静态成员变量占内存 因此,类的内存分布=所有的非静态成员变量+虚指针(自创的名词:即指向虚函数表的指针) 2.虚函数的原理 一个非继承的类:一个虚指针(指向他的虚函数表). 一个单继承的类:一个虚指针(指向他的虚函数表,这个虚函数表

第13周项目2-纯虚函数形类家庭

写一个程序.定义一个抽象基类Shape,它是从衍生3派生类.Circle(周围).Rectangle(矩形).Triangle(三角).例如,下面的main()性能.划定区域并找到一些几何. int main() { Circle c1(12.6),c2(4.9);//建立Circle类对象c1,c2,參数为圆半径 Rectangle r1(4.5,8.4),r2(5.0,2.5);//建立Rectangle类对象r1,r2,參数为矩形长.宽 Triangle t1(4.5,8.4),t2(3.

C++ 虚函数实现多态浅析

这几天深入学习了一下c++多态,趁此总结了一下多态中的虚函数,先看一下c++多态中的定义 多态定义: 父类指针指向子类对象,通过父类指针或引用可以调用到正月版本的函数. 而本文主要尝试解释:为什么父类指针指向子类对象,通过父类指针或引用可以调用到正月版本的函数? 如有大牛有更好解释,还望共同探讨.废话不说,直接进入正题 先定义四个类 如下: // //  main.cpp //  project13 // //  Created by 就不告诉你我是谁 on 15-8-7. //  Copyri

&lt;转&gt;C++继承中虚函数的使用

转自:http://blog.csdn.net/itolfn/article/details/7412364 一:继承中的指针问题. 1. 指向基类的指针可以指向派生类对象,当基类指针指向派生类对象时,这种指针只能访问派生对象从基类继承 而来的那些成员,不能访问子类特有的元素 ,除非应用强类型转换,例如有基类B和从B派生的子类D,则B *p;D  dd; p=&dd;是可以的,指针p只能访问从基类派生而来的成员,不能访问派生类D特有的成员.因为基类不 知道派生类中的这些成员. 2. 不能使派生类

C++ Primer 学习笔记_22_类与数据抽象(8)--static 成员变量、static 成员函数、类/对象的大小

一.static 每个static数据成员是与类关联的对象,并不与该类的对象相关联!非static数据成员存在于类类型的每个对象中,static数据成员独立该类的任意对象存在. static成员函数没有this形参,它可以直接访问所属类的static成员,但是不能直接使用static成员! 1.static 成员变量 对于特定类型的全体对象而言,有时候可能需要访问一个全局的变量.比如说统计某种类型对象已创建的数量. 如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个全局变量,这时可