C++模板:静多态

本文探讨了动多态(虚函数)和静多态(模板)在处理对象统一操作时的区别。动多态允许在运行时处理异类集合,但会产生额外的开销;而静多态在编译时确定类型,提高了效率,但不支持异类集合。以桥接模式为例,展示了两者在实现上的差异。C++ STL的迭代器是一个使用模板实现静多态的典型例子,其在容器扩容时能保持指针的有效性。
摘要由CSDN通过智能技术生成

一般,使用虚函数和继承实现的是动多态,即在运行期间确定调用者的类型。使用模板,可以实现静多态,在编译期间确定调用者的类型。

例如我们要对某一类对象进行统一处理,使用虚函数可以这样实现:

class BaseType
{
public:
	virtual void action1(){...}
    virtual void action2(){...}
}

class SubType1 : BaseType
{
public:
    virtual void action1(){...}
    virtual void action2(){...}
}

class SubType2 : BaseType
{
public:
    virtual void action1(){...}
    virtual void action2(){...}
}

// 统一处理
void DoAction1(BaseType const& type)
{
    type.action1();
}

void DoAction2(BaseType* type)
{
    type->action2();
}

// 可以处理异类集合
void DoActions(std::vector<BaseType*> list) 
{
    ...
}

如果使用模板来实现,就会变成这样

class SubType1
{
public:
    void action1(){...}
    void action2(){...}
}

class SubType2
{
public:
    void action1(){...}
    void action2(){...}
}

// 统一处理
template<typename BaseType>
void DoAction1(BaseType const& type)
{
    type.action1();
}

template<typename BaseType>
void DoAction2(BaseType* type)
{
    type->action2();
}

// 不可以处理异类集合,因为要在编译期间确定,vector只能为一个类型的集合
template<typename BaseType>
void DoActions(std::vector<BaseType*> list)  // 处理异类集合会报错
{
    ...
}
动多态和静多态两者的优点

动多态:

  1. 可以处理异类集合
  2. 生成的代码比较小,只需要一个多态函数,而静多态会生成多个实例化函数

静多态:

  1. 不需要和公共基类绑定,可以自由实现处理类型
  2. 代码运行效率更高,直接调用函数,虚函数间接调用;比虚函数拥有更多内联的机会
使用模板实现Bridge Pattern

用一个指针引用具体的实现,然后把所有的调用都委托给这个(包含这个指针)的类。

使用多态实现:

// 实现的接口基类
class Implementation
{
	virtual operationA() = 0;
    virtual operationB() = 0;
    virtual operationC() = 0;
}

// 实现A
class ImplementationA : Implementation
{
    virtual operationA(){...}
    virtual operationB(){...}
    virtual operationC(){...}
}

// 实现B
class ImplementationB : Implementation
{
    virtual operationA(){...}
    virtual operationB(){...}
    virtual operationC(){...}
}

class Bridge
{
public:
    // 通过将body指向不同的实现类来调用不同的实现
    Implementation* body;
    
    void operationA()
    {
        body->operationA();
    }
    
    void operationB()
    {
        body->operationB();
    }
}

使用模板实现,即使用静多态:

// 实现A
class ImplementationA : Implementation
{
    virtual operationA(){...}
    virtual operationB(){...}
    virtual operationC(){...}
}

// 实现B
class ImplementationB : Implementation
{
    virtual operationA(){...}
    virtual operationB(){...}
    virtual operationC(){...}
}

template<typename Implementation>
class Bridge
{
public:
    // 使用不同的类型来生成不同实现的实例化类
    Implementation* body;
    
    void operationA()
    {
        body->operationA();
    }
    
    void operationB()
    {
        body->operationB();
    }   
}

使用模板实现桥接模式的一个例子就是C++STL的迭代器,通过迭代器间接执行元素的操作。在容器扩容的时候,有时会重新申请一块内存,并将原来的数据转移过去,如果外面有指针指向容器内的元素,那么这个指针就会失效,如果是指向迭代器,那么就不会有问题。

template<typename T>
class Iterator
{
private:
	T value;
public:
    T operator+(T const& right){...}
    ...
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值