Chinaunix首页 | 论坛 | 博客
  • 博客访问: 667650
  • 博文数量: 150
  • 博客积分: 4070
  • 博客等级: 中校
  • 技术积分: 1795
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-23 21:44
文章分类

全部博文(150)

文章存档

2012年(1)

2011年(123)

2010年(26)

分类: C/C++

2011-01-03 21:37:40

1. MFC类库中,CObject类的重要性不言自明。在CObject的定义中,我们看到一个有趣的现象,即CObject的析构函数是虚拟的。为什么MFC的编写者认为虚拟构造函数是必要的?
答:首先构造一个类
class CBase
{
   public:
     ~CBase()  {...........}
   .....
};
 
class CChild:public CBase
{
   ~CChild()   {...........}
  ......
};
 
main()
{
   CChild c;
   .......
   return 0;
}
上段代码在运行时,由于在生成CChild对象c时,实际上在调用CChild类的构造函数之前必须调用基本CBase的构造函数,所以在撤销对象c时,也会在调用CChild类析构函数之后,在调用CBase类的析构函数(析构函数的调用顺序与构造函数相反)。也就是说,无论析构是不是虚函数,派生类对象被撤销时,肯定会依次上调基类的析构函数。而之所以CObject类要搞一个虚的析构函数是因为多态性的存在。仍以上面的代码为列子,如果main中有如下代码:
CBase *pBase;
CChild c;
pBase = &c;
那么在pBase指针被撤销时,调用的是CBase的析构函数还是CChild的呢?显然是CBase的(静态联编)析构函数。但如果把CBase类的析构函数改成为virtual型,当pBase指针被撤销时,就会先调用CChild类的析构函数,在调用CBase类的析构函数。
在这个例子中,所有对象都存在于栈框中,当离开其所处的作用域时,该对象会被自动撤销,似乎看不出什么大问题。但是如果在CChild类的构造函数中分配了内存,而其析构函数又不是virtual型的,那么撤销pBase时,将不会调用CChild的析构函数,从而不会释放内存,造成内存泄露。
将CObject的析构函数设为virtual型,则所有CObject类的派生类的析构函数都将自动变成virtual型,这保证了在任何情况下,不会出现由于析构函数未被调用而导致的内存泄露。这才是MFC将CObject类的析构函数设为virtual的真正原因。
 
2. 析构函数可以为virtual型,构造函数则不能,那为什么构造函数不能为虚的呢?
答:虚函数采用一种虚调用的办法。虚调用是一种可以在只有部分信息的情况下工作的机制,特别允许我们调用一个只知道接口而不知道其准确对象类型的函数。但是如果要创建一个对象,你势必要知道对象的准确类型,因此构造函数不能为虚的。
 
3. 如果虚函数是非常有效的,我们是否可以把每个函数都声明为虚函数?
答:不行,这是因为虚函数是有代价的,由于每个虚函数的对象都必须维护一个v表,因此使用虚函数的时候都会产生一个系统开销。如果仅仅是一个很小的类,且不想派生其他类,那么根本没有必要使用虚函数。
 
4. 析构函数可以是内联函数吗?
答:析构函数可以是内联函数。
 
 
 
 
 
 
阅读(3319) | 评论(1) | 转发(0) |
0

上一篇:QoS控制

下一篇:ARQ协议

给主人留下些什么吧!~~

chinaunix网友2011-01-05 11:05:55

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com