条款41:了解隐式接口和编译器多态——229

显示接口和运行期多态——229

我们来看这样的例子:

class Widget{
public:
    Widget();
    virtual ~Widget();
    virtual std::size_t size() const;
    virtual void normalize();
    void swap(Widget& other);
    ...
};

void doProcessing(Widget& w)
{
    if(w.size()>10 && w!= someNastyWidget){
        Widget temp(w);
        temp.normalize();
        temp.swap(w);
    }
}

此例中的w就有显式接口和运行期多态性:
(1)由于w的类型被声明为Widget,所以w必须支持Widget接口。我们可以在源码中找出这个接口,看看它是什么样子,所以称此为一个显示接口,也就是它在源码中明确可见。
(2)由于Widget的某些成员函数是virtual,w对那些函数的调用将表现出运行期多态,也就是说将于运行期根据w的动态类型决定究竟调用哪一个函数。

隐式接口和编译器多态——230

我们将上节的doProcessing从函数转变成函数模板时反生什么事:

template<typename T>
void doProcessing(T& w)
{
    if(w.size()>10 && w!= someNastyWidget){
        Widget temp(w);
        temp.normalize();
        temp.swap(w);
    }
}

此例中的w就有隐式接口和编译期多态性:
(1)w必须支持哪一种接口,是由template中执行与于w身上的操作来决定。本例看来w的类型T好像必须支持size,normalize和swap成员函数、copy构造函数、不等比较。这一组表达式(对此template而言必须有效编译)便是T必须支持的一组隐式接口。
(2)凡涉及w的任何函数调用,例如operator>和operator!=,有可能造成template具现化,使这些调用得以成功。这样的具现行为发生在编译器。“以不同的template参数具现化function template”会导致调用不同的函数,这便是所谓的编译器多态。

总结——233

(1)class和template都支持接口和多态。
(2)对class而言接口是显式的,一函数签名为中心。多态则是通过virtual函数发生在运行期。
(3)对template参数而言,接口是隐式的,奠基于有效表达式。多态则是通过template具现化和函数重载解析发生于编译器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值