本文将介绍如何在继承关系中实现父类函数调用子类函数的两种方法。

父子类关系

在继承关系中,子类是父类的一种特殊形式,子类继承了父类的属性和行为。因此,子类可以访问父类的所有非私有成员。相反,父类通常不能访问子类的成员。然而,我们可以通过一些方法间接地实现父类访问子类,即父类函数访问子类函数。

方法一:利用多态机制

一个指向子类的父类指针或引用,当调用被子类重写的虚函数时,实际上调用的是子类函数。这是通过多态的方式来实现父类调用子类。该方法需要一个引用或者指针调用虚函数来实现。
参考之前发的博客:C++子类实现父类纯虚函数实现父类获取子类信息

上面的例子就是通过多态实现的父类调用子类成员函数,这里面必须要有虚函数,并且在子类里面重写。

方法二:通过函数指针

通过函数指针同样可以实现父类函数访问子类函数,示例代码如下:

#include<iostream>
using namespace std;
class Base {
	public:
		typedef void (Base::*pfn)();

		void CallFunction() {
			if(fn != NULL) {
				(this->*fn)();  //调用Derived类中的fun()函数
			}
		}
		void SetPfn(pfn fn) {
			this->fn = fn;
		}

		pfn fn;

};

class Derived : public Base {
	public:

		void Init() {
			SetPfn((pfn)&Derived::fun);
		}
		void funDer() {
			(this->*fn)();
		}
		void fun() {
			std::cout << "Derived::fun be called in Base function!" << std::endl;
		}

};
int main() {

	Derived derived;
	derived.Init();
	derived.CallFunction();//这里调用的是父类的成员函数,该函数通过函数指针调用了子类的普通成员函数,调用结果输出:"Derived::fun be called in Base function!",即父类成员函数调用了子类成员函数。
	derived.funDer();//这里是在子类中调用父类的成员变量,该变量是函数指针指针调用了子类的普通成员函数,调用结果输出:"Derived::fun be called in Base function!",即父类成员函数调用了子类成员函数。
}

关于函数指针

函数指针在C++中有许多优点:

  • 灵活性:函数指针可以在运行时决定调用哪个函数,这使得程序更加灵活。例如,你可以根据用户的输入或其他条件来决定调用哪个函数。

  • 回调函数:函数指针常常用于实现回调函数,这是一种在特定事件或条件发生时自动执行的函数。例如,你可以创建一个函数,当某个特定事件发生时,这个函数就会被自动调用。

  • 抽象和封装:函数指针可以用于实现抽象和封装。你可以创建一个接受函数指针作为参数的函数,然后在这个函数内部调用传入的函数。这样,你就可以在不知道具体实现的情况下调用函数,只需要知道函数的接口。

  • 实现多态:在C++中,虽然我们有虚函数来实现多态,但在某些情况下,我们也可以使用函数指针来实现多态。例如,你可以创建一个基类指针,然后将它指向一个派生类对象,然后通过这个指针调用派生类的函数。

  • 性能优化:在某些情况下,使用函数指针可以提高程序的性能。例如,如果你有一个经常被调用的小函数,你可以将它的地址存储在一个函数指针中,然后通过这个指针来调用这个函数,这样可以避免每次都要查找这个函数的地址。

总的来说,函数指针是一种非常强大的工具,它可以使你的程序更加灵活,更加抽象,也可以帮助你优化你的程序。

爱死C++了,家人们 谁懂啊,太神奇了。

06-02 23:11