欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

虚函数用法总结

程序员文章站 2024-03-21 12:01:46
...
#include<iostream>
using namespace std;
class Class {};
class Base :public Class
{
public:
	Base() = default;
	Base(const Base&a) :ival(a.ival), dval(a.dval)
	{
		cout << "---Base----" << endl;
	}
	Base(int a, int b) :ival(a), dval(b)
	{
		cout << "---Base-a----" << endl;
		printf("a11= %d,b11= %d\n", a, b);
	}
	// virtual void print(){
	// 	printf("%d---1---%d\n",dval,ival );
	// }
	void print() {
		printf("%d---1---%d\n", dval, ival);
	}
	int dval;
protected:
	int ival;
};
class D1 :   public Base//因为是虚基,因此可以有不同形参的同名函数print;若不是虚基,则不可以有不同形参的同名函数
{
public:
	D1() = default;
	D1(const D1&a) :Base(a.ival, a.dval)
	{
		cout << "---D1----" << endl;
	}
	D1(int a, int b) :Base(a, b)
	{
		cout << "---D1-a----" << endl;
	}
	// void print(int a)
	// {
	// 	printf("---2---%d----2---\n", a);
	// }
};
int main()
{
	D1*pi;
	int i = 4, j = 7;
	pi = new D1(i, j);
	//对于Mi而言,使用Final中的Mi类进行初始化
	Base*pmi = new Base(*pi);//指向虚基类,但并未初始化
	pi->print(111);
}

#include<iostream>
using namespace std;
class Class {};
class Base :public Class
{
public:
	Base() = default;
	Base(const Base&a) :ival(a.ival), dval(a.dval)
	{
		cout << "---Base----" << endl;
	}
	Base(int a, int b) :ival(a), dval(b)
	{
		cout << "---Base-a----" << endl;
		printf("a11= %d,b11= %d\n", a, b);
	}
	// virtual void print(){
	// 	printf("%d---1---%d\n",dval,ival );
	// }
	void print() {
		printf("%d---1---%d\n", dval, ival);
	}
	int dval;
protected:
	int ival;
};
class D1 :  public Base//因为是虚基,因此可以有不同形参的同名函数print;若不是虚基,则不可以有不同形参的同名函数
{
public:
	D1() = default;
	D1(const D1&a) :Base(a.ival, a.dval)
	{
		cout << "---D1----" << endl;
	}
	D1(int a, int b) :Base(a, b)
	{
		cout << "---D1-a----" << endl;
	}
	void print()
	{
		printf("---2---%d----2---\n", ival);
	}
};
class D2 :virtual public Base
{
public:
	D2() = default;
	D2(const D2&a) :Base(a.ival, a.dval)
	{
		cout << "---D2----" << endl;
	}
	D2(int a, int b) :Base(a, b)
	{
		cout << "---D2-a----" << endl;
	}
};
class Mi :public D1/*,public D2*/
{
public:
	Mi() = default;
	Mi(const Mi&a) :Base(a.ival, a.dval)/*,D2(a.ival,a.dval)*/, D1(a.ival, a.dval)
	{
		cout << "---Mi----" << endl;
	}
	Mi(int a, int b) :Base(a, b), D1(a, b)/*,D2(a,b)*/
	{
		cout << "---Mi-a----" << endl;
		printf("a= %d,b= %d\n", a, b);
	}
};
class Final : public Mi, public Class
{
public:
	Final() = default;
	Final(const Final&a) :Base(a.ival, a.dval), Mi(a.ival, a.dval)
		// Final(const Final&a):Base(a.ival,a.dval),Mi(1,2)
	{
		cout << "---Final----" << endl;
	}
	// Final(int a,int b):Base(a,b),Mi(a,b)
	Final(int a, int b) :Base(a, b), Mi(1, 2)//首先Base被Base初始化了,然后Mi中的Base基类初始化就不再调用了
	{
		cout << "---Final-a----" << endl;
	}
};
int main()
{
	Final*pi;
	int i = 4, j = 7;
	pi = new Final(i, j);
	//对于Mi而言,使用Final中的Mi类进行初始化
	Mi*pmi = new Mi(*pi);//指向虚基类,但并未初始化
	pmi->print();
}

两段代码,可以调着进行理解使用

1.     只有一个基被标记为虚基,才能允许被间接访问

2.     当一个基,用派生类来构造它自己时,最后执行的函数,是基中的函数非派生类中的函数;同时,它也只能调用自己的函数,不能调用派生类中的函数

3.     派生类可以继承基类中的函数(即使没有在派生类中写出来);当写出来时,则派生类执行自己类内部的成员函数,不执行基类中的成员函数(非虚函数),但成员函数之间要求同名同形参

4.     当基类中的某个成员函数是虚函数时,则后面派生类中的同名成员函数可以有不同的形参

5.     总结:

a)      虚基,可以间接调用

b)      虚函数,派生类的同名函数可以有不同形参(当然也可以不写出来默认使用基类中的)


相关标签: 虚函数 虚基