Virtual的一些总结

一、函数的隐藏与覆盖

        曾经看孙鑫的《VC++深入详解》,在C++基础中提到过函数的隐藏与覆盖,不懂的同学可以去搜,当时没能理解其精髓,后来看到ACE代码,很多析构函数都是虚函数后,开始去搜了。

        继承是动态多态的支撑点,继承的时候,public的成员和方法都是直接可以使用的,当子类函数与父类函数同名时,父类方法就被隐藏了;而如果父类方法是虚函数,则父类方法被覆盖(Java貌似是直接写override,重写)。当然,要覆盖,必须函数列表相同,位于父类和子类中,必须声明virtual。

        以如下测试代码为例

//============================================================================
// Name        : Iherit.cpp
// Author      : xia
// Copyright   : NUAA
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;

class Person {

public :
	Person() {
		cout << "Person constructor" << endl;
	}
	virtual ~Person() {
		cout << "Person destructor" << endl;
	}
	virtual void say() {
		cout << "Person says " << endl;
	}

};

class boy:public Person {

public:
	boy() {
		cout << "boy constructor" << endl;
	}
	virtual ~boy() {
		cout << "boy destructor" << endl;
	}
	void say() {
		cout << "boy says " << endl;
	}

};

int main() {
	Person *xiaoli = new boy;
	xiaoli->say();
	delete xiaoli;
	return 0;
}

     当去掉Person类中say()方法 前的virtual后,输出结果为

Person constructor
boy constructor
Person says
boy destructor
Person destructor

       由于没有virtual关键字,没有通过v-table找到子类的say方法,所以虽然是子类对象,由于是父类指针,依旧调用了父类方法(如果想多态,这肯定不是我们的目的;毕竟多态的一个大应用就是向上转换,统一用父类指针调用子类方法),加上virtual后,则输出boy says


二、virtual与构造函数、析构函数

        《C++编程思想》上有说过,构造函数不能为虚函数,为什么呢?一个原因是虚函数能调用在派生类的函数,如果我们在构造函数中这样,我们调用的函数可能操作还没有初始化的成员(因为子类对象要先调用父类的构造函数),这会导致灾难发生。另一个原因是,当一个构造函数被调用时,它要做的首要事情之一是初始化它的VPTR。

         不过很多时候析构函数却必须为虚函数,为什么呢?同样是由于当父类指针指向子类对象时,如果父类析构不是虚函数,则执行时,不能执行到子类的析构函数。以上面示范代码为例,如果去掉Person中析构函数的virtual关键字,则输出

Person constructor
boy constructor
Person says
Person destructor

        并没有调用到boy的析构函数,加上后,可以看到是调用了的。

        以前测试代码,并没有使用父类指针去指向子类对象,忘了充分使用多态,所以并没有体会到隐藏和覆盖 以及虚函数的一些更 high的地方,正好碰到了,就总结下吧。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值