[11 使用C++11开发一个轻量级的IoC容器(工厂模式的应用及优化)] 11.3 类型擦除的常用方法

类型擦除就是将原有类型消除或隐藏。类型擦除可以使得程序获得更好的扩展性,消除耦合。

下面是常见的类型擦除方式:

1 多态

2 模板

3 类型容器Variant

4 通用类型Any

5 闭包

1 多态

通过将派生类型隐式转换为基类型,再通过基类去调用虚函数。这样就把派生类型转成基类型隐藏起来。多态方式的类型擦除只是部分擦除,因为基类型还在;且需要继承关系,强耦合。

2 模板

本质上是把不同类型的共同行为进行了抽象,不需要再通过继承这种强耦合方式去获取共同的行为。存在的问题是,不能把T本身作为容器元素,必须在容器初始化时指定T为某个具体类型。

3 类型容器Variant

Variant可以把各种不同的类型包起来,获得一种统一的类型,它是个类型容器。例如,可以通过Variant这样擦除类型:

typedef Variant<double, int, uint32_t, char*> Value;
vector<Value> vt;
vt.push_back(1);
vt.push_back("test");
vt.push_back(1.22);

通过Get<T>()就可以获取对应类型的值。这种方式通过把类型包起来,达到类型擦除的目的。缺点是通用的类型必须提前定义好。

4 通用类型Any

通用类型Any类似Java中的Object,介绍用Any类型擦除的方法:

vector<Any> v;
v.push_back(1);
v.push_back("test");
v.push_back(2.35);
auto r1 = v[0].AnyCast<int>();
auto r2 = v[1].AnyCast<const char*>();
auto r3 = v[2].AnyCast<double>();

Any允许任何类型的对象都赋值给Any对象。缺点是取值的时候仍需要具体的类型,可通过闭包改进。

5 闭包

闭包就是能够读取其他函数内部变量的函数。如lambda表达式。闭包将类型信息保存在闭包中,从而隐藏了类型信息,实现类型擦除的目的。因为闭包本身类型是确定的,可以放到普通容器中,在需要时可从闭包中取出具体的类型。看下如何通过闭包擦除类型:

template<typename T>
void Func(T t)
{
    cout << t << endl;
}

void TestErase()
{
    int x = 1;
    char y = 's';

    vector<std::function<void()>> v;
    // 类型擦除,闭包中隐藏了具体的类型(x,y)
    v.pushback([x]{ Func(x); });
    v.pushback([y]{ Func(y); });
    
    // 遍历闭包,取出实际的参数
    for (auto item:v)
    {
        item();
    }
}

IoC容器主要用到通用类型Any和闭包来擦除类型。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值