Chinaunix首页 | 论坛 | 博客
  • 博客访问: 72158
  • 博文数量: 15
  • 博客积分: 760
  • 博客等级: 军士长
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-16 21:07
文章分类
文章存档

2011年(1)

2009年(11)

2008年(3)

我的朋友

分类: C/C++

2009-02-28 17:01:02

几个例子如下:
1。普通虚函数
class C1
{
public:
 C1()
 {};
 virtual F1()
 {}
};
printf("vftptr count :%d\n" , sizeof(C1) / 4);结果为1
2。含有继承的虚函数

class C2 : public C1
{
public:
 C2(){
  printf("In C1\n");
  DispVFT((DWORD*)this);
 }
 virtual F2()
 {}
};

虚函数的表数为1,地址相同。即C1,C2的地址相同,虚函数表相同。

3。一对多的继承

class C1
{
public:
 C1()
 {}
 virtual F1(){}
};

class C2
{
public:
 C2(){}
 virtual F2(){}
};
class C3 : public C1 , public C2
{
public:
 C3(){}
 virtual F3(){}
};

虚函数表指针的个数等于基类的个数。至于虚函数表的个数,应该是三个。可以把我在构造函数中加的代码去掉注释符,看看输出。你会发现每次输出的表的首地址都是不一样,那表当然也不是同一个表。

在C3的实例被构造出来后,只有最后一个表,也就是C3的表在用,其它的表跟本就是没有用的,C++在没有通过你同意的情况下,在浪费你的空间(多重继承也存在同样的问题)。微软想了个办法把其它的不用的虚函数表去掉:__declspec(novtable)


class __declspec(novtable)C1
{
public:
 C1()
 {}
 virtual F1(){}
};

可以看到一切正常,只是在不知不觉中,你的程序瘦身成功,不过如果你决定要去掉类的虚函数表,你最好可以确定这个类应该是个被继承的基类,而不是最后派生使用的类。否则可能会出错,比如:

void func1(C1* p)
{
 p->F1();
}
void main()
{
 C2 c2;
 func1(&c2);
}

阅读(1512) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~