查看: 2354|回复: 42

C++虚函数简要总结

[复制链接]
发表于 2012-8-31 06:40:06 | 显示全部楼层 |阅读模式
 关于C++如何实现虚函数,不需要详细说了,大概说一下。把一个子类对象赋给基类指针,且调用一个虚函数,此时指针会执行子类对象,因为vptr是在对象的开头部分,自然的,会指向vptr指向的函数地址,也就是vtable,vtable是每个类都有的,每个类都会记录该类的虚函数地址,如果重写了基类的虚函数,那vtable里面会更新相应的地址,否则依旧以父类虚函数地址。Vtable里面的次序是严格限定的,以基类里面的次序为次序。注意vptr是继承的。且引入创建默认构造函数一个原因就是创建vptr。

  为什么需要virtual这个关键字,原因是如果我们不需要虚函数机制的时候可以不使用,除非到了非得使用的时候,这样子做是为了效率。

  纯虚函数可以提供定义,但是不能在类里内联定义,应该在类外定义。即使抽象类所有虚函数都定义了,依然不能创建抽象类对象。子类继承基类切不实现基类的虚函数,编译器会报错。(p378)

  如果子类新加了虚函数,会将虚函数地址放在vtable最后。(p379)

  对象切片(Object Slicing):如果以传值方式传递,会发生对象切割,把属于子类的东西给切割了。传值只拷贝基类部分。且vptr也转换为基类的vptr。如果参数是抽象类的对象,是无法通过编译的,因为抽象类是不能产生对象的。(p381)

  子类可以对父类虚函数进行重载(可以改变参数列表),但不能改变其返回值。如果子类重载了父类的虚函数,则子类对象调用该函数时,隐藏了父类的虚函数。

  例外!如果父类的虚函数返回的是父类的指针,此时子类可以改变虚函数返回类型。

  抽象类只能作为基类使用,不能声明抽象类对象,构造函数不能是虚函数,析构函数可以是虚函数。
  在构造函数调用虚函数,调用的是本类的虚函数,虚函数在构造函数无法发挥作用。

  构造函数在类的层次上是从上到下的,所以在类里面调用虚函数,使用的是自己的vptr,因为此时子类还没初始化,所以调用的将是自己的虚函数,而不是子类的。

  析构函数中多态机制也不起作用,因为析构函数的调用是从子类往父类析构的,所以如果在基类里调用了虚函数,如果这个虚函数是子类的vptr,那么此时父类应该调用子类的函数,但是此时子类已经被析构掉了。

  存在向下转型(父类对象赋给子类指针),但是很危险,可以用dynamic_cast。

发表于 2012-8-31 09:33:30 | 显示全部楼层
必须顶  
发表于 2012-9-1 09:51:50 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
发表于 2012-9-1 14:04:43 | 显示全部楼层
哈哈,有意思~顶顶 ,继续顶顶。继续顶哦  
发表于 2012-9-1 22:46:50 | 显示全部楼层
顶你一下,好贴要顶!  
haha 该用户已被删除
发表于 2012-9-2 21:53:05 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
发表于 2012-9-2 23:43:52 | 显示全部楼层
问渠哪得清如许,为有源头活水来。  
发表于 2012-9-3 00:21:27 | 显示全部楼层
一个人最大的破产是绝望,最大的资产是希望。  
发表于 2012-9-3 06:46:29 | 显示全部楼层
不错!  
发表于 2012-9-3 08:56:48 | 显示全部楼层
慢慢来,呵呵  
高级模式
B Color Image Link Quote Code Smilies

本版积分规则