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

【C++】多态(一)

程序员文章站 2024-02-29 23:31:16
...

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

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;
}

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

【C++】多态(一)

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;
}

运行结果:

【C++】多态(一)

如图:函数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构成了重写,满足了多态的条件,这个例子就是协变

  【C++】多态(一)

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

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

【面试题】

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

【C++】多态(一)