Chinaunix首页 | 论坛 | 博客
  • 博客访问: 84867
  • 博文数量: 18
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 321
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-30 21:09
文章分类

全部博文(18)

文章存档

2015年(3)

2014年(9)

2013年(6)

我的朋友

分类: C/C++

2014-01-25 11:08:53

#include
class CPerson {
public:
    CPerson() {
        ShowSpeak(0);
    }   
    virtual ~CPerson() {
        ShowSpeak(1);
    }   
    virtual void ShowSpeak(int i) {
        if(0 == i)
            printf("%s::ShowSpeak()\r\n", GetClassName());
        else 
            printf("~%s::ShowSpeak()\r\n", GetClassName());
    }   
    virtual char* GetClassName() {
        return "CPerson";
    }   
};
class CChinese : public CPerson {
public:
    CChinese() {
        ShowSpeak(0);
    }   
    virtual ~CChinese() {
        ShowSpeak(1);
    }   
    virtual char* GetClassName() {
        return "CChinese";
    }   
};
int main() {
    CPerson *pPerson = new CChinese();
    pPerson->ShowSpeak(0);
    delete pPerson;
}

执行上面的程序,输出结果为:
CPerson::ShowSpeak()
CChinese::ShowSpeak()
CChinese::ShowSpeak()
~CChinese::ShowSpeak()
~CPerson::ShowSpeak()

从上面的输出结果中可以看到,虽然在CPerson的构造和析构函数中,调用了ShowSpeak虚函数,但实际的输出结果却没有调用CChinese::ShowSpeak()
原因是在任何一个类的析构和构造函数中,都会用本类的虚表指针替换当前this中的虚表指针,这样无论自己的构造和析构函数中怎么直接或间接调用其它函数,都能确保调用的是本类虚表的函数。
为什么要这么处理呢?
从析构来讲,是先析构子类,再析构父类;若在父类中通过虚表调用了子类的虚函数,由于子类已经被析构,这个调用就会出问题;
从构造来讲,是先构造父类,再是子类,子类都还没有构造完成,父类更加不能利用子类的虚表去调用了;
上面两个就是C++的语言规则,虚函数的正确使用是有明确限制的;

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