继承之虚函数+空类大小
来源:互联网 发布:java反复执行一个任务 编辑:程序博客网 时间:2024/04/30 22:06
虚函数的思想是从Simula借来的,并经过一定修改获得的。引入虚函数是为了增加程序设计的灵活性。
一个基类的虚函数在不同的派生类里面可以有不同的实现。
在关于对象布局方面。C++把一个类中所有的虚函数定义成一个指向函数的指针数组。可以通过调用这个指针数组中的函数指针来指向需要调用的虚函数(有点绕口了~)。简单的说,就是通过调用函数指针来调用虚函数,而这个函数指针被存储在一个指针数组中。这个指针数组就是通常所说的虚函数表或vtbl。每个有虚函数的类的对象都会有一个隐式的指针,叫做vptr,指向这个对象的类的虚函数表(vtbl)。
空类的大小为什么为1?
首先,我们要清楚实例化是什么意思。所谓的实例化就是在内存中分配一块地址,而每个实例都会有一块独一无二的地址。按照语法,我们可以知道,空类也是可以被实例化的,那么问题来了,如果空类的大小为0,要怎么为空类分配一块独一无二的地址呢?所以,为了达到这个目的,编译器往往会向空类里面隐含的加一个字节,这样就可以在内存中获得一块第一无二的地址啦。所以空类的大小就变成1啦。
编译器在处理类的大小时,因为大多数CPU对字长的整数倍操作起来会更快,所以,编译器会做出一些优化,在类成员之间或者最后插入一段内存,让空类的大小达到字长的整数倍,这个叫做“补齐”(padding)。所以,C++标准紧紧规定成员的排列按照类定义的顺序,但是不要求在存储器中是紧密排列的。
在C++中基类希望派生类进行覆盖的函数通常会定义为虚函数。当我们使用指针或者引用调用函数的时候,这个调用将会被动态绑定。根据引用和指针绑定的对象类型的不同,虚函数会执行不同的版本。如果指针或者引用绑定的是基类,那么执行的就是基类的虚函数,如果是派生类那么就是派生的虚函数。(每个基类通常都应该定义一个虚析构函数,即使这个虚析构函数什么都不做。)成员函数如果没有被声明为虚函数,其解析过程发生在编译时而不是运行时。
但是派生类也可以不重写继承自基类的虚函数。如果派生类没有重写基类中的某个函数,那么派生类就会直接继承这个函数在基类中的版本。
例如:
#include <iostream>class A{public : virtual void f(){ std::cout << "this is A" << std::endl; } virtual void g(){ std::cout << "this is A's g" << std::endl; }};class B : public A{public : virtual void g(){ std::cout << "this is B's g" << std::endl; }};int main(){ B b; b.f(); b.g(); system("PAUSE"); return 0;}
0 0
- 继承之虚函数+空类大小
- 空类,虚函数类,虚继承类的空间大小
- 空类、含静态成员的类、普通类(不含虚函数、虚继承)的sizeof大小
- 空类大小和虚函数的大小
- 空类及其继承类的大小
- C++继承、虚继承、虚函数类的大小问题
- C++继承、虚继承、虚函数类的大小问题
- C++继承、虚继承、虚函数类的大小问题
- C++继承、虚继承、虚函数类的大小…
- C++继承、虚继承、虚函数类的大小…
- C++继承、虚继承、虚函数类的大小问题
- C++继承、虚继承、虚函数类的大小问题
- C++继承、虚继承、虚函数类的大小问题
- C++继承、虚继承、虚函数类的大小问题
- C++继承、虚继承、虚函数类的大小问题
- C++继承、虚继承、虚函数类的大小问题
- C++继承、虚继承、虚函数类的大小问题
- 关于空类,含有虚函数的类的大小
- 寒假英语学习总结
- 全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?
- sql经典问题集全
- ngnix fanxiangdaili
- listview有header时position不对
- 继承之虚函数+空类大小
- jQuery中$(function()与(function($)等的区别详细讲解
- Java并发编程:Thread类的使用(很好)
- IntelliJ IDEA 基本配置入门
- shell学习笔记:控制结构
- C语言程序的存储区域
- how to create an ssl certificate on nginx for ubuntu14.04
- 离散化+扫描线 poj1151
- ruby连接mysql问题处理办法汇总