继承之虚函数+空类大小
2015-02-28 11:03
211 查看
虚函数的思想是从Simula借来的,并经过一定修改获得的。引入虚函数是为了增加程序设计的灵活性。
一个基类的虚函数在不同的派生类里面可以有不同的实现。
在关于对象布局方面。C++把一个类中所有的虚函数定义成一个指向函数的指针数组。可以通过调用这个指针数组中的函数指针来指向需要调用的虚函数(有点绕口了~)。简单的说,就是通过调用函数指针来调用虚函数,而这个函数指针被存储在一个指针数组中。这个指针数组就是通常所说的虚函数表或vtbl。每个有虚函数的类的对象都会有一个隐式的指针,叫做vptr,指向这个对象的类的虚函数表(vtbl)。
空类的大小为什么为1?
首先,我们要清楚实例化是什么意思。所谓的实例化就是在内存中分配一块地址,而每个实例都会有一块独一无二的地址。按照语法,我们可以知道,空类也是可以被实例化的,那么问题来了,如果空类的大小为0,要怎么为空类分配一块独一无二的地址呢?所以,为了达到这个目的,编译器往往会向空类里面隐含的加一个字节,这样就可以在内存中获得一块第一无二的地址啦。所以空类的大小就变成1啦。
编译器在处理类的大小时,因为大多数CPU对字长的整数倍操作起来会更快,所以,编译器会做出一些优化,在类成员之间或者最后插入一段内存,让空类的大小达到字长的整数倍,这个叫做“补齐”(padding)。所以,C++标准紧紧规定成员的排列按照类定义的顺序,但是不要求在存储器中是紧密排列的。
在C++中基类希望派生类进行覆盖的函数通常会定义为虚函数。当我们使用指针或者引用调用函数的时候,这个调用将会被动态绑定。根据引用和指针绑定的对象类型的不同,虚函数会执行不同的版本。如果指针或者引用绑定的是基类,那么执行的就是基类的虚函数,如果是派生类那么就是派生的虚函数。(每个基类通常都应该定义一个虚析构函数,即使这个虚析构函数什么都不做。)成员函数如果没有被声明为虚函数,其解析过程发生在编译时而不是运行时。
但是派生类也可以不重写继承自基类的虚函数。如果派生类没有重写基类中的某个函数,那么派生类就会直接继承这个函数在基类中的版本。
例如:
一个基类的虚函数在不同的派生类里面可以有不同的实现。
在关于对象布局方面。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; }
相关文章推荐
- C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- 空类、含静态成员的类、普通类(不含虚函数、虚继承)的sizeof大小
- C++ 06 继承与组合 (has-a is-a) 以及类大小的计算 虚基类对内存模型的影响(不考虑虚函数)
- 虚函数工作原理 与 (继承中)对象占用空间大小
- [置顶] 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- C++类对象大小的计算(三)含有虚函数、虚继承类大小计算
- C++:C++ 空类的大小及相关继承类的大小
- 空类,虚函数类,虚继承类的空间大小
- 大小测试(空类、带含静态和非含、虚和非虚的单继承和多继承等)
- 关于空类,含有虚函数的类的大小
- [置顶] 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- 虚继承和虚函数对c++对象存储模型的影响(类/对象的大小)
- 空类大小及指针转换(多继承)
- 从零开始学C++之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- Data语意学之虚继承和虚函数对C++对象内存模型造成的影响(类/对象的大小)
- C++虚函数及其继承、虚继承类大小
- 关于求虚函数的和虚继承中的大小
- 空类大小及指针转换(单继承)
- 空类,虚函数类,虚继承类的空间大小
- C++ 空类的大小和存在虚函数时类的大小