c++类继承中的虚函数

方法在基类中被声明为virtual的后,它在派生类中将自动成为虚方法。此时我们在派生类中将此方法声明不声明为virtual都没关系了,但是最好是声明出来好标记哪些方法是虚的。

析构函数和构造函数要被声明为虚函数吗:

继承体系中,析构函数应该被声明为虚函数。如果不声明为虚函数,一个基类指针指向派生类对象时,delete这个指针时,将只会调用这个指针类型的(基类的)析构函数。如果声明为虚函数后,使用的将是晚期联编,会在程序运行时,判断调用哪个函数。会根据这个指针指向的对象类型来确定,因此会调用派生类的析构函数。

构造函数不用声明为虚函数,因为在构造这个派生类时,会先调用基类构造函数,再调用它自己的。

 

class Base {
public:
	Base() { cout << "base contructor" << endl; };
	virtual ~Base() { cout << "base destructor" << endl; };
};
class Derived :public Base {
public:
	Derived() { cout << "derived contructor" << endl; };
	virtual ~Derived() { cout << "derived destructor" << endl; };
};

int main() {

	Base* p = new Derived;  //输出base constructor,derived constructor
	delete p;     //输出derived destructor,base destructor
	return  0;
}

 

按值赋值与按指针或引用赋值的不同:

按值赋值导致只将Derived对象d的Base部分传给bv。所以调用的func函数也是Base的。但是派生类引用或指针在赋值时,可以被转换为基类引用或指针(隐式向上强制转换)。

#include<iostream>
using namespace std;

class Base {
public:
	virtual void func() { cout << "base function" << endl; }
};

class Derived :public Base {
public:
	virtual void func() { cout << "derived function" << endl; }
};

int main() {
	Derived d;

	Base *bp=&d;
	bp->func();   //输出derived function	

	Base bv = d;
	bv.func();    //输出base function	
}

虚函数的工作原理:

虚函数使用的是晚期联编,只有在程序运行时才能确定到底要调用哪个函数。含有虚函数的类会有一个虚函数表,这个表里存放着它所有虚函数的地址。类的每个对象会添加一个指向虚函数表的指针。基类中有虚函数,它会有一张虚函数表。从基类派生出来的派生类,也会有一张虚函数表。它拷贝基类的虚函数表。如果派生类重写了基类中的虚函数,那么新的函数地址会覆盖原先的函数地址。在派生类中新加的虚函数也会加到该表后面。

 

多继承下的虚函数:

他继承的所有基类中,有多少个带虚函数的基类,派生类就会有多少个虚函数表,他会把他们的虚函数表都拷贝一份。派生类会重写每一个基类的每一个同名函数。派生类中新加入的虚函数,会加入到第一个虚函数表后面。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值