zoukankan      html  css  js  c++  java
  • Effective C++ 笔记 —— Item 41: Understand implicit interfaces and compiletime polymorphism.

    Look what happens when we turn doProcessing from a function into a function template:

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

    Now what can we say about w in doProcessing?

    • The interface that w must support is determined by the operations performed on w in the template. In this example, it appears that w's type (T) must support the size, normalize, and swap member functions; copy construction (to create temp); and comparison for inequality (for comparison with someNastyWidget). We'll soon see that this isn’t quite accurate, but it's true enough for now. What’s important is that the set of expressions that must be valid in order for the template to compile is the implicit interface that T must support.
    • The calls to functions involving w such as operator> and operator!= may involve instantiating templates to make these calls succeed. Such instantiation occurs during compilation. Because instantiating function templates with different template parameters leads to different functions being called, this is known as compile-time polymorphism.

    An explicit interface typically consists of function signatures, i.e., function names, parameter types, return types, etc. The Widget class public interface, for example,

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

    An implicit interface is quite different. It is not based on function signatures. Rather, it consists of valid expressions. Look again at the conditional at the beginning of the doProcessing template:

    template<typename T>
    void doProcessing(T& w)
    {
        if (w.size() > 10 && w != someNastyWidget)
        {
            // ...
        }
    
        // ...
    }

    Things to Remember:

    • Both classes and templates support interfaces and polymorphism.
    • For classes, interfaces are explicit and centered on function signatures. Polymorphism occurs at runtime through virtual functions.
    • For template parameters, interfaces are implicit and based on valid expressions. Polymorphism occurs during compilation through template instantiation and function overloading resolution.
  • 相关阅读:
    为什么要有红黑树?什么是红黑树?画了20张图,看完这篇你就明白了
    都2020年了,听说你还不会归并排序?手把手教你手写归并排序算法
    为什么会有多线程?什么是线程安全?如何保证线程安全?(带详细例子)
    微信小程序APP(商超营销类)经验总结
    CheckBox的OnCheckedChangeListener事件
    Android常用的工具类
    【原创】【Android】揭秘 ART 细节 ---- Garbage collection
    18级软件工程1班第一次作业总结
    HUST软工1506班第2周作业成绩公布
    HUST软件测试1506班: 第0周作业成绩
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/15665716.html
Copyright © 2011-2022 走看看