虚函数通俗理解,使用虚函数的场景,小白必看

本文以通俗易懂的方式解释了C++虚函数的概念和使用场景,通过起床穿衣的例子展示了虚函数如何让父类决定调用时机,子类决定具体实现。此外,还探讨了虚函数的类内实现、类外实现、纯虚函数以及子类指针赋值给父类的应用。在实际编程中,虚函数常用于库的接口设计,如Qt的绘图事件。了解这些知识点有助于提升面向对象编程的能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

虚函数通俗理解,使用虚函数的场景,小白必看

1、为何要用虚函数。

网上有许多关于介绍虚函数的理解,或是写一堆代码,但是,对于小白而言,很难理解虚函数的用处,以及在什么情况下用。

一句话说明虚函数的使用场景:父类决定调用时机,子类决定具体实现。

举个每天八点起床穿衣的例子,假设我们每天八点早上都要起床,穿衣服。而穿衣事件,都发生在早上八点。那么,我们可以将穿衣服这个函数的调用时机在父类中确定,也就是每天八点会调用穿衣函数。而具体穿什么衣服,每天都不一样,每天穿什么样的衣服,就在子类中具体实现,用代码表示就是:

class father
{
public:
	void clock_8() //每天8点钟的时候
	{
		//执行穿衣函数
		dress();
	}
	//穿衣函数,是个纯虚函数,具体实现在子类中实现
	//这样,父类就决定了,这个穿衣函数的调用时机
	virtual void dress() = 0;
};

class child1 : public father
{
public:
	//子类决定了,穿衣函数的具体实现
	virtual void dress() 
	{
		cout << "穿红衣服" << endl;
	}
};

int main()
{
	child1 c;
	//这样子类,每天起床时,都会调用,穿衣服
	c.clock_8();
	return 0;
}

我们在使用一些官方库的时候,比如使用Qt时,绘图事件这个函数的调用时机有很多,比如改变窗口的大小,点击窗口中的按钮,都会触发绘图事件并调用绘图函数。而这些调用时机我们很难自己去确定,这时,Qt官方库会帮我们确定调用的时机。

而具体需要绘制什么样的内容,需要我们自己去实现,这时,C++为我们提供了虚函数来实现这个需求。

2、虚函数若干问题

1、虚函数的类内实现
子类实现虚函数,可以加virtual关键字,也可以不加virtual关键字

class CFather
{
public:
	virtual void func()
	{
		cout << "父类 func" << endl;
	}
};

class CChildren : public CFather
{
public:

	//子类的virtual 关键字,加不加效果一样,建议加上
	virtual void func()
	{
		cout << "子类 func" << endl;
	}
};

2、虚函数的类外实现
类外实现,类内先申明,类外不写virtual关键字

class CFather
{
public:
	virtual void func()
	{
		cout << "父类 func" << endl;
	}
};

class CChildren : public CFather
{
public:
	//类内申明
	virtual void func();
};

//类外实现,类内先申明,类外不写virtual关键字
	void CChildren::func()
	{
		cout << "子类 func" << endl;
	}

3、纯虚函数
父类有纯虚函数,父类变成抽象类,是无法实例对象的

class CFather
{
public:
//纯虚函数格式
	virtual void func()=0;
};

class CChildren : public CFather
{
public:
	//子类的virtual 关键字,加不加效果一样,建议加上
	virtual void func()
	{
		cout << "子类 func" << endl;
	}
};
int main()
{
	//报错,抽象类无法实例对象
	//CFather far;
}

4、子类指针赋值给父类
这种操作是将子类的指针赋值给父类,这种操作比较特殊

class CFather
{
public:
	virtual void func()
	{
		cout << "父类 func" << endl;
	}
};

class CChildren : public CFather
{
public:

	//子类的virtual 关键字,加不加效果一样,建议加上
	virtual void func()
	{
		cout << "子类 func" << endl;
	}
};

int main()
{
	//注意这里,只能把儿子指针赋值给爸爸,反过来报错
	CFather* son2 = new CChildren;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值