美文网首页
奇异递归模板模式 (CRTP, Curiously Recurr

奇异递归模板模式 (CRTP, Curiously Recurr

作者: fck_13 | 来源:发表于2020-09-02 12:58 被阅读0次

    这个名字念起来有些拗口,先看一下代码示例:

    // The Curiously Recurring Template Pattern (CRTP)
    template<class T>
    class Base{
        // methods within Base can use template to access members of Derived
    };
    class Derived : public Base<Derived>{
        // ...
    };
    

    这是CRTP一个最基本的形式,可以看出,将派生类作为基类的模板参数,意味基类可以访问派生类的一些内容,这也是名字中为什么会有递归两个字的原因。

    下面是一些CRTP的使用示例:

    静态多态

    template <class T>
    struct Base{
        void interface(){
            static_cast<T*>(this)->implementation();
        }
    
        static void static_func(){
            T::static_sub_func();
        }
    };
    
    struct Derived : Base<Derived>
    {
        void implementation(){
        }
        static void static_sub_func();
    };
    
    void Derived::static_sub_func(){
    }
    
    int main(){
        Derived d{};
        d.static_func();
        return 0;
    }
    

    代码注入

    template <typename T>
    struct counter{
        static int objects_created;
        static int objects_alive;
    
        counter(){
            ++objects_created;
            ++objects_alive;
        }
    
        counter(const counter&){
            ++objects_created;
            ++objects_alive;
        }
    
        ~counter(){ // objects should never be removed through pointers of this type
            --objects_alive;
        }
    };
    template <typename T> int counter<T>::objects_created( 0 );
    template <typename T> int counter<T>::objects_alive( 0 );
    
    struct MyClass : public counter<MyClass>
    {};
    
    int main(){
        MyClass h{};
        {
            MyClass a{};
            MyClass c{};
            MyClass d{};
        }
        return MyClass::objects_alive;
    }
    

    单例模式

    #include <memory>
    
    template <class ActualClass>
    class Singleton{
    public:
        static ActualClass& GetInstance(){
           if(p == nullptr)
             p = std::unique_ptr<ActualClass>(new ActualClass);
           return *p;
         }
    
       protected:
        Singleton() = default;
        static std::unique_ptr<ActualClass> p;
    };
    template <class T>
    std::unique_ptr< T > Singleton<T>::p;
    
    class A: public Singleton<A>
    {
    };
    
    int main(){
        auto& i = A::GetInstance();
    }
    

    最佳实践

    namespace detail{
        template <class T>
        class Base{
        public:
            void interface()
            {
                // ...
                self()->implementation();
                // ...
            }
        private:
            T* self(){
                return static_cast<T*>(this);
            }
            // methods within Base can use template to access members of Derived
        };
    };
    
    class Derived : public detail::Base<Derived>{
    public:
        void implementation(){
            // do something
        }
        // ...
    };
    
    int main(){
        Derived d;
        d.interface();
    }
    

    C++ 库中,std::shared_ptr中的std::enable_shared_from_this使用了CRTP.

    相关文章

      网友评论

          本文标题:奇异递归模板模式 (CRTP, Curiously Recurr

          本文链接:https://www.haomeiwen.com/subject/cjwprktx.html