虚函数与纯虚函数

静态多态——函数重载

动态多态——虚函数

#include <iostream>
using namespace std;

class father {
	public:
		virtual void A() {
			cout << "father" << endl;
		}
		void B() {
			A();
		}
};

class son: public father {
	public:
		void A() {
			cout << "son" << endl; 
		}
};

int main() {
	son s;
	cout << "s.B()" << endl;
	s.B();
	
	father f = s;
	cout << endl << "f.B()" << endl;
	f.B();
	
	cout << endl << "s.A()" << endl;
	s.A();
	cout << "s.father::A()" << endl;
	s.father::A();
	
	cout << endl << "s.father::B()" << endl; 
	s.father::B(); //在这里等价于s.B() 
	cout << "(father)s.B()" << endl;
	((father)s).B();
	
	father *pf = new son();
	cout << endl << "pf->B()" << endl;
	pf->B();
	return 0;
}

执行结果:

程序运行结果

 

父类和子类出现同名函数称为隐藏。

  • 父类对象.函数名(...);     //调用父类的函数
  • 子类对象.函数名(...);           //调用子类的函数  
  • 子类对象.父类名::函数名(...);//子类调用从父类继承来的函数。

父类和子类出现同名虚函数称为覆盖

  • 父类指针=new 子类名(...);父类指针->函数名(...);//调用子类的虚函数。

 

通过父类指针操作子类对象的成员函数的时候是没有问题的,可是在销毁对象内存的时候则只是执行了父类的析构函数,子类的析构函数却没有执行,这会导致内存泄漏。为解决内存泄漏问题,引入虚析构函数。

虚析构函数的实现原理

[:->虚析构函数的特点:

  • 当我们在父类中通过virtual修饰析构函数之后,通过父类指针指向子类对象,通过delete接父类指针就可以释放掉子类对象

[:->理论前提:

  • 执行完子类的析构函数就会执行父类的析构函数

注:

1)普通函数不能是虚函数,这个函数必须是某一个类的成员函数,不可以是一个全局函数。

2)友元函数不能做虚函数。

3)静态成员函数不能做虚函数,static成员函数是和类同生共处的,不属于任何对象,使用virtual将导致错误。

4)内联函数不能是虚函数,如果内联函数被virtual修饰,计算机会忽略inline使它变成纯粹的虚函数。

(inline函数在编译时被展开,在调用处将整个函数替换为代码块,省去了函数跳转的时间,提高了SD,减少函数调用的开销,虚函数是为了继承后对象能够准确的调用自己的函数,执行相应的动作。

主要的原因是:inline函数在编译时被展开,用函数体去替换函数,而virtual是在运行期间才能动态绑定的,这也决定了inline函数不可能为虚函数。(inline函数体现的是一种编译机制,而virtual体现的是一种动态运行机制)

5)构造函数和拷贝构造函数不能是虚函数,但析构函数可以是虚函数。

 

纯虚函数:

没有函数体,同时在定义的时候要在后面加"=0"。


    virtual void func() = 0;

含有纯虚函数的类被称为抽象类,抽象类不允许实例化对象。

仅含有纯虚函数的类被称为接口类,接口类自身不能实例化,接口类的方法定义/实现只能由接口类的子类完成。

对于C++,接口类一般具有以下特征:

1)最好不要有成员变量,但可以有静态常量(static const或enum)

2)接口方法都要声明称纯虚函数

3)要有虚析构函数,最好提供默认实现(如果接口类的析构函数是纯虚析构函数的话,接口类的子类将被迫必须提供析构函数的实现,这样对接口类的子类不友好)

4)不声明构造函数。

https://www.cnblogs.com/jin521/p/5602190.html c++深入理解虚函数

https://blog.csdn.net/a15929748502/article/details/80920132 c++虚函数的作用及实现原理

https://blog.csdn.net/netyeaxi/article/details/80724557 C++如何正确的定义一个接口类

https://blog.csdn.net/netyeaxi/article/details/80887646 C++如何正确使用接口类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值