【C++】多态(一)

     这篇博客简单介绍了多态的概念,分类,动态多态实现的条件,重写等几个方面,希望能够加深对于多态的理解。

1.概念

多态:指的是同一个事物的多种表现形态

2.多态的分类

分为:

1)静态多态:编译器在编译期间来确定程序的行为(确定具体调用哪个函数)

       a)函数重载

       b)泛型编程

2)动态多态:在程序运行时,根据基类的指针(引用)指向的对象来确定调用哪个类的虚函数

3.代码实现一个多态,多态的例子

我们实现一个基类是student,派生类为graduate

class Student
{
public:
	//构造函数
	Student(int n, string name, float score)
		:_num(n)
		, _name(name)
		, _score(score)
	{};

	//输出函数
	virtual void Display()
	{
		cout << "num:" << _num << endl;
		cout << "name:" << _name << endl;
		cout << "score:" << _score << endl;
	}

protected:
	int _num;
	string _name;
	float _score;
};

class Graduate :public Student
{
public:
	//构造函数
	Graduate(int n, string name, float score, float p)
		:Student(n, name, score)
		, _pay(p)
	{};

	//对基类的Display进行重写
	virtual void Display()
	{
		cout << "num:" << _num << endl;
		cout << "name:" << _name << endl;
		cout << "score:" << _score << endl;
		cout << "pay:" << _pay << endl;
	}

protected:
	float _pay;
};

void TestVirtualFunc(Student& s,const string str)
{
	cout << str << endl;
	s.Display();
	cout << endl;
}
int main()
{
	Student s(1,"张三",90);
	Graduate g(2,"李四",80,100);
	TestVirtualFunc(s,"Student:");
	TestVirtualFunc(g,"Graduate:");
	return 0;
}

结果:实现了调用同一个函数结果不同的情况,这就是多态


4.动态多态实现的条件

1)基类中必须包含虚函数,并且派生类中一定要对基类中的虚函数进行重写

2)通过基类对象的指针或者引用调用虚函数

那么什么是重写呢?

如下代码:

class Base
{
public:
	virtual void Func1()
	{
		cout << "Base::Func1" << endl;
	}

	virtual void Func2()
	{
		cout << "Base::Func2()" << endl;
	}

	void Func3()
	{
		cout << "Base::Func3()" << endl;
	}

	virtual void Func4()
	{
		cout << "Base::Func4()" << endl;
	}
};

class Derived:public Base
{
public:
	virtual void Func1()
	{
		cout << "Derived::Func1()" << endl;
	}

	//基类的Func2中有virtual,派生类中没有
	void Func2()
	{
		cout << "Derived::Func2()" << endl;
	}

	//基类的Func3中没有virtual,派生类中有
	virtual void Func3()
	{
		cout << "Derived::Func3()" << endl;
	}

	//基类和派生类的参数列表不一致
	virtual void Func4(int)
	{
		cout << "Derived::Func4()" << endl;
	}
};

//通过基类的引用来调用虚函数
void TestVirtualFunc(Base& b,const string& str)
{
	cout << str << endl;
	b.Func1();
	b.Func2();
	b.Func3();
	b.Func4();
	cout << endl;
}

int main()
{
	Base b;
	Derived d;
	TestVirtualFunc(b,"Base:");
	TestVirtualFunc(d,"Derived");
	return 0;
}

运行结果:


如图:函数Func1和Func2构成了多态,Func3和Func4未构成多态,原因是不满足构成多态的条件1,没有构成重写,那么什么是重写呢?

5.重写

重写要满足以下几个条件:

a)基类中的函数必须为虚函数

b)派生类中重写的虚函数必须与基类的虚函数原型保持一致(返回值,函数名字,参数列表)

  例外

  (1)协变:返回值类型不同,

            基类中的虚函数返回基类对象的指针(引用)

           派生类的虚函数返回派生类对象的指针(引用)

           这种情况也会产生重写

   如下代码:

在Base类中新增加Func3函数
virtual Base& Func3()
{
	cout << "Base::Func3()" << endl;
	return *this;
}
在Derived中新增加Func3函数:
virtual Derived& Func3()
{
	cout << "Derived::Func3()" << endl;
	return *this;
}

  结果:Func3构成了重写,满足了多态的条件,这个例子就是协变

  

(2)析构函数:基类和派生类的函数名字不同,这种情况也会产生重写

c)基类的虚函数和派生类的虚函数访问限定符可以不同

【面试题】

什么是函数重载,同名隐藏和重写?



       

猜你喜欢

转载自blog.csdn.net/zimituanzi_/article/details/80935886