C++ 多态虚函数常见问题

哪些函数不能为虚函数?
  • 非类成员的普通函数
  • 静态(static)函数
  • 构造函数不能是虚函数
    • (存储角度)虚函数的vtable,是存储在对象的内存空间的。对象没有实例化,意味着内存空间还没有,所以无法找到对应的vtable;
    • (调用角度)虚函数的作用在于父类的指针或者引用,根据动态类型调用(指向)子类的成员函数。构造函数本身需要初始化实例,所以不可能通过父类指针或引用来调用,所以不可能为虚函数,即使是虚函数也没有实际意。
  • 友元函数,友元函数不属于类的成员函数,不能被继承。
内联函数是否可以为虚函数(虚函数可以是内联函数)?
  • 虚函数可以是内联函数;
  • inline是可以修饰虚函数;
  • 编译器具有实际对象非指针或引用时可以内敛,但此时虚函数没有表现出多态性
    参考:
    虚函数可以是内联函数吗?
析构函数是否可以为虚函数?

可以

虚析构函数是为了解决基类的指针指向派生类对象,并用基类的指针删除派生类对象。


#include <iostream>
#include <memory>
using namespace std;
class SoftWare {
public:
	SoftWare(){};
	virtual ~SoftWare() { 
		std::cout << __FUNCTION__ << std::endl; 
	};
	//运行期多态
	virtual void RunApp() { std::cout << " Interface SoftWare " << std::endl; };
};

class ChatApp : public SoftWare {
public:
	ChatApp(){};
	~ChatApp() { 
		std::cout << __FUNCTION__ << std::endl; 
	};
	void RunApp() { std::cout << " Start Chat APP " << std::endl; }
};

int main()
{
	SoftWare* app = new ChatApp();
	std::cout << "================================" << std::endl;
	app->RunApp();
	delete app;
	app = nullptr;
	/*由于SoftWare有虚析构函数,delete释放内存会先调用派生类析构函数,再调用基类析构函数,防止内存泄漏。*/	
	std::cout << "================================" << std::endl;
	return 0;
}
虚析构函数存在的原因:
  • delete释放基类指针时,编译器会根据类型来调用类的成员函数,首先调用基类的析构函数,如果有派生类,则会根据虚表继续调用派生类的析构函数。
  • 假设基类的析构函数为非虚函数时,当释放一个基类指针指向的派生类实例时,则只清理了派生类从基类继承过来的虚函数,而派生类自己独有的资源却没有被清理。
为什么默认的析构函数不是虚函数?

节省内存

类中有虚成员函数时,类会自动进行执行一些工作。包括生成虚函数表和虚表指针,这样会占用额外的内存,如果类无派生类,这种内存开销无疑是浪费;

什么是纯虚函数?

纯虚函数是在基类中声明的虚函数,它在基类中有定义,在派生类必须定义自己的实现方法。基类不能创建对象,可以使用指针或者引用派生类对象。语法上基类声明纯虚函数的方法,是在函数原型后加“=0”

virtual int TestFunc() = 0;
  • 含有纯虚函数的类叫抽象类,抽象类不能直接创建对象。只有被继承并重写其纯虚函数后,才能使用。
  • 抽象类被继承后,子类可以继续是抽象类,也可以是普通类
纯虚函数存在的原因及意义?
  • 为了使用多态特性,需要在基类中定义虚拟函数,很多时候,基类本身生成对象是不合情理的。从面向接口编程出发,接口可以被实例化,这违背了“接口”本身的意义。
  • 纯虚函数存在:让所有继承抽象类的派生类都可以执行纯虚函数的动作,但抽象类不会为纯虚函数提供一个默认方法。强行让派生类实现属于自己的虚函数方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值