多态的四种表现形式

多态的四种表现形式

在之前一提到多态,我下意识就是虚函数重写构成的运行时多态。直到看了一篇文章,才反应过来多态有四种表现形式。cpp-polymorphism

  • 运行时多态(虚函数)
  • 编译时多态(模板)
  • 重载
  • 类型转换

运行时多态(Subtype Polymorphism/Runtime Polymorphism)

运行时多态就是派生类重写基类的虚函数,在调用函数里,参数为基类的指针或引用,会构成多态。我之前写过一篇多态的原理,就是在讲多态(运行时多态)在底层是怎么实现的

多态的实现原理

举个例子:比如买票这个行为,成人去买就是全价,学生买就是半价票。但是不管成人还是学生都是人这个体系。所以我们需要根据谁来买票才能决定价格,这个时候就需要多态。

#include 

class ticket
{
public:
	virtual void price() = 0;
};

class adult : public ticket
{
public:
	virtual void price() override
	{
		std::cout << "成人全价!" << std::endl;
	}
};

class student : public ticket
{
public:
	virtual void price() override
	{
		std::cout << "学生半价!" << std::endl;
	}
};

void BuyTicket(ticket& t)
{
	t.price();
}

int main(void)
{
	adult a;
	student s;

	BuyTicket(a);
	BuyTicket(s);
	return 0;
}

多态的四种表现形式_第1张图片

编译时多态(Parametric Polymorphism/Compile-Time Polymorphism)

编译时多态就是模板。在程序编译时,编译器根据参数的类型,就将生成某种类型的函数或类。我之前关于模板的总结:

C++泛类–函数模板、类模板

举个简单的例子:Add() 函数是一个非常简单的函数,但是如果你写一个整型的 Add 函数,那么我想加 double 型的呢?你再写一个 double 型的 Add 函数,那么我想加 char 型的呢?

这个时候就用到了模板,我们先定义一个逻辑,具体类型等编译时再生成该类型的函数或类。

#include 

template<class T>
T Add(T lhs, T rhs)
{
	return lhs + rhs;
}

int main(void)
{
	Add(1, 2);
	Add(2.0, 3.0);
	Add('a', 'b');
	return 0;
}

重载(Ad-hoc Polymorphism/Overloading)

函数名相同,参数不同就构成了重载。重载主要用于函数,当某个函数的功能无法处理某些参数的情况时,我们就可以重载一个函数来单独处理。

举个例子:比如说上面的 Add 函数,当前内置类型都可以处理,但是如果我传两个字符串怎么办?就不可以像刚才那么加了。得重载一个函数单独处理。

#include 
#include 

int Add(int lhs, int rhs)
{
	return lhs + rhs;
}

std::string Add(const std::string& lhs, const std::string& rhs)
{
	std::string ans(lhs);
	ans += rhs;

	return ans;
}

int main(void)
{
	Add(1, 2);
	Add("abc", "def");

	return 0;
}

类型转换(Coercion Polymorphism/Casting)

类型转换主要分为四种:

  • static_cast: 相当于隐式类型转换。
  • const_cast: 这个可以去除一个 const 变量的 const 性质,使可以改变它的值。
  • reinterpret_cast: 相当于强制类型转换。
  • dynamic_cast: 这个可以使子类指针或引用赋值给父类指针或引用。

类型转换很简单,这里就不多赘述了。

Ending

这篇博客主要是强调了多态有四种形式,并不单单是运行时多态。

你可能感兴趣的:(C++知识点)