C++的动态多态与静态多态
Posted 飞鹤0755
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++的动态多态与静态多态相关的知识,希望对你有一定的参考价值。
1. 概述
C++是一门面向对象的编程语言。面向对象的一个最重要特征,即面向接口编程。面向接口编程,可以降低代码的耦合度,提高维护代码的可靠性。而面向接口编程是通过多态这一语言特征来实现的。
2. 动态多态
2.1. 概念
顾名思义,动态多态,即在运行时,也即代码执行时表现出来的多种状态。
- 在语法层面,是通过使用virtual标记基类的函数,然后在派生类中重写此函数。在代码执行时,通过基类指针或引用的真实派生类型来调用派生类中的实现。
- 在实现层面,主要是通过虚函数表来实现的。基类有virtual函数,则有一个虚函数表,那么派生类也会有一上自己的虚函数表。调用虚函数时,与指针类型无关,而与指针指向的具体是哪一个对象,调用的时候就会去查找相应对象的虚函数表,找到并执行相应虚函数。
class CUI
{
public:
virtual ~CUI(){}
virtual void OnPaint()
{
std::cout<< "Paint" <<std::endl;
}
};
class CNormalUI : public CUI
{
public:
virtual void OnPaint()
{
std::cout<< "Normal Paint" <<std::endl;
}
};
class CColorUI : public CUI
{
public:
virtual void OnPaint()
{
std::cout<< "Colorfullly Paint" <<std::endl;
}
};
int main(int argc, char **argv)
{
CUI* p = new CNormalUI();
p->OnPaint(); // Normal Paint
delete p;
p = new CColorUI();
p->OnPaint(); // Colorfullly Paint
delete p;
return 0;
}
2.2. 优点
- 增加新的实现,不用修改以前的代码,减少对过往功能可靠性的影响。
- 实现接口保持一致,可以更方便地添加新的实现。
2.3. 缺点
- 动态多态是通过虚函数表来实现的,每个派生类实现的虚函数并不固定,所以虚函数表大小并不固定,这就导致每次虚函数的调用,都需要有一个查找虚函数表的过程,这就导致调用虚函数的性能会降低。
- 虚函数表与普通成员函数的内存分配并不是在一起的,也就是说虚函数表的设计并不是Cache友好型设计,这就导致CPU的流水线在执行代码时,代码的命中效率会降低,降低虚函数的调用性能。
3. 静态多态
3.1. 概念
静态多态,是指在编译期间实现的多态。有人将函数重载理解为静态多态,但是函数重载要求形参不同,这与虚函数实现的多态有较大差异。此处讲的静态多态,与虚函数实现的动态多态类型,函数名相同,函数参数也相同。这主要是通过一种CRTP(curiously recurring template pattern)技术来实现的,即一个类X派生自以X为模板形参的类模板实例。
下面的代码,主要依靠模板实例化时才编译,以及派生类可以访问基类模板类中的成员及方法。需要注意的是,派生类函数的调用是通过强制类型转换来实现的,这里的强制转换是不安全的,所以派生类实现无法访问派生类中的其他成员。
template<class T>
class CUI
{
public:
void OnPaint()
{
static_cast<T&>(*this).OnPaintImpl();
}
void OnPaintImpl()
{
std::cout<< "Paint" <<std::endl;
}
};
class CNormalUI : public CUI<CNormalUI>
{
public:
void OnPaintImpl()
{
std::cout<< "Normal Paint" <<std::endl;
}
};
class CColorUI : public CUI<CColorUI>
{
public:
void OnPaintImpl()
{
std::cout<< "Colorfullly Paint" <<std::endl;
}
};
int main(int argc, char **argv)
{
CUI<CNormalUI> ui1;
ui1.OnPaint();
CUI<CColorUI> ui2;
ui2.OnPaint();
return 0;
}
4. 比较
- 动态多态更加灵活,适合更复杂的应用场景。
- 静态多态是编译期实现的多态,效果更高,适用于对性能要求高的场景,如UI渲染等。
以上是关于C++的动态多态与静态多态的主要内容,如果未能解决你的问题,请参考以下文章