C++ 虚函数 动态绑定 的问题

一、关于C++动态绑定的问题,来来回回看了很多遍,现在终于有点稍微的理解。谈下自己的想法。

参考文章:(写得很好)  http://blog.csdn.net/haoel/article/details/1948051/

为什么析构函数要声明为虚函数   http://www.cnblogs.com/lixiaohui-ambition/archive/2012/07/13/2589716.html

二、自己的一些理解

1、CPP Plus中说,C++中实现动态绑定需要有两个基本条件

  a.指向基类的指针和引用

  b.子类对基类的虚函数进行重定义。(函数定义原型完全一样,除一个特例,下面介绍)

#ifndef _VIRTUAL_H_
#define _VIRTUAL_H_
using namespace std;
class A{
public:
    virtual void p()
    {
        cout<<"A"<<endl;
    }
    virtual ~A()
    {
        cout<<"deconstruction A"<<endl;
    }
};

class B: public A {
public:
    void p()
    {
        cout<<"B"<<endl;
    }
    ~B()
    {
        cout<<"deconstruction B"<<endl;
    }
};
class C: public B {
public:
    void p()
    {
        cout<<"C"<<endl;
    }
    ~C()
    {
        cout<<"deconstruction C"<<endl;
    }
};
#endif

如上代码,A为基类,B public 继承 A。 C public 继承 B。
补充一些继承的概念:所有基类的成员变量和成员数据在派生类中都存在。继承的权限只是决定派生类的对象是否有访问基类的权利。

#include "stdafx.h"
#include <iostream>
#include "virtual.h"

int _tmain(int argc, _TCHAR* argv[])
{
    A *a = new A;
    A *b = new B;
    A *c = new C;
    a->p();
    b->p();
    c->p();
    delete a;
    delete b;
    delete c;
    system("pause");
    return 0;
}

动态绑定的实现:如上代码,生成 A、B、C三类对象,都使用基类的指针来指向该内存空间。执行p()函数时(p函数实现了重定义),将根据动态绑定选择执行哪个类的函数(满足C++动态绑定的两个要求)
动态绑定的实质是:对虚表的查询(详解链接一中说明)。虚表中保存每个函数的实际地址。

其实对于 class C 的 p()函数是virtual函数,则无论使用 A *c = new C, 或 B *c = new C, 还是 C *c = new C, 使用 c->p(),调用的都是 class C 中重定义过的 p()

但是如果 class C 的 p() 函数不是virtual函数:

#则使用 A *c = new C, c->p() 调用的是class A 中的 p(),

#使用 B *c = new C, c->p() 调用的是class B 中的 p(),

#使用 C *c = new C, c->p() 调用的是class C 中的 p().

 

2、为什么虚构函数要使用虚函数

调用派生类的虚构函数执行后,默认调用基类的析构函数。虚构函数声明为虚函数,主要是:当使用delete释放指向基类的指针时,可以正确地选择要调用的虚构函数。实现虚构函数的动态绑定。

注意:虽然每个派生类的虚构函数名称不同,但是实质上是同一类型。基类的析构函数声明为虚函数,则子类的虚函数在虚表里覆盖基类的析构函数。

 

3、虚函数重定义

虚函数的重定义必须保证函数原型的一致,否则将被认为是新的函数,而不是对基类虚函数的重定义。有两个特例

  a.如 3 中所说,析构函数虽然名称不同,但属于重定义。

  b.若基类虚函数的返回值是基类的引用或指针,则子类重定义虚函数的返回值可以是子类(或父类)的引用和指针

 

3、虚函数的意义

还在思考中。(TODO)

 

 

 

posted on 2014-04-17 22:02  themo  阅读(651)  评论(0编辑  收藏  举报

导航