虚函数通俗理解,使用虚函数的场景,小白必看
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;
}