现在的位置: 首页 > 综合 > 正文

虚函数表和虚函数表的指针

2013年08月11日 ⁄ 综合 ⁄ 共 1001字 ⁄ 字号 评论关闭

    有虚函数的类都有一个虚函数表,它是实现多态的关键。

    虚函数表可以继承,如果子类没有重写虚函数,那么子类虚函数表中仍然会有该函数的地址,只不过这个地址指向的是基类的函数实现。如果子类重写了相应的虚函数,那么虚函数表中的地址就会改变,指向自身的函数实现。如果派生类中有自己的虚函数,那么虚函数表中会添加该项。

    每个对象调用的虚函数都是通过虚函数表 指针来索引的,因此虚函数表指针的正确初始化是非常重要的。虚函数表指针应该在什么时候、什么地方初始化呢?

    应该在构造函数中进行虚函数表的创建和虚函数表指针的初始化。根据构造函数的调用顺序,在构造子类对象时,要先调用父类的构造函数,此时编译器只看到了父类,并不知道后面是否有继承者,所以它只初始化父类对象的虚函数表指针,该虚函数表指针指向父类的虚函数表;当执行子类的构造函数时,子类对象的虚函数表指针被初始化,指向自身的虚函数表。

#include <iostream>
using namespace std;

class A {
public:
	virtual void f() {
		cout << "f in A." << endl;
	}
	virtual void g() {
		cout << "g in A." << endl;
	}
	void h() {
		cout << "h in A." << endl;
	}
};

class B : public A {
	void f() {
		cout << "f in B." << endl;
	}
};

int main () {
	cout << "sizeof(A):" << sizeof(A) << endl; 
	cout << "sizeof(B):" << sizeof(B) << endl; 
	A *p = NULL;
	B b;
	p = &b;
	p->f();
	p->g();
	p->h();

	return 0;
}

上面的代码中,当B类的对象b构造完成后,其内部的虚函数表指针被初始化为指向B类的虚函数表。

类的成员函数不占用类的空间,它们存储在另外的一个地方;只要类中有虚函数,这个类就会有一个对应的虚函数表,而类会增加一个指向这个虚函数表的指针,B继承了一个类A,所以需要一个指向虚函数表的指针,32位系统下指针的大小为4字节。如果继承了N个类,则对应需要N个指针,分别指向对应的虚函数表。

[root@zhuliting ~]# g++ -o test test.cpp
[root@zhuliting ~]# ./test
sizeof(A):4
sizeof(B):4
f in B.
g in A.
h in A.

抱歉!评论已关闭.