最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++ CRTP模式的使用小結(jié)

 更新時間:2026年03月08日 11:06:22   作者:a353541382  
CRTP是C++中一種高級的模板編程技術(shù),它通過將派生類作為基類的模板參數(shù)來實現(xiàn)編譯期多態(tài),本文就來介紹一下c++ CRTP模式的使用小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

CRTP(Curiously Recurring Template Pattern,奇異遞歸模板模式)是C++中一種高級的模板編程技術(shù),它通過將派生類作為基類的模板參數(shù)來實現(xiàn)編譯期多態(tài)。

1. CRTP的基本概念

基本結(jié)構(gòu)

// 基類模板
template<typename Derived>
class Base {
public:
    void interface() {
        // 將調(diào)用轉(zhuǎn)發(fā)給派生類的實現(xiàn)
        static_cast<Derived*>(this)->implementation();
    }
    
    void static_interface() {
        // 調(diào)用派生類的靜態(tài)方法
        Derived::static_implementation();
    }
};

// 派生類
class Derived : public Base<Derived> {  // 關(guān)鍵:將自己作為模板參數(shù)
public:
    void implementation() {
        std::cout << "Derived implementation" << std::endl;
    }
    
    static void static_implementation() {
        std::cout << "Derived static implementation" << std::endl;
    }
};

2. CRTP的核心原理

編譯期多態(tài)

template<typename Derived>
class Base {
public:
    // 編譯期多態(tài):調(diào)用哪個implementation在編譯時確定
    void foo() {
        static_cast<Derived*>(this)->implementation();
    }
    
    // 可以添加默認實現(xiàn)
    void bar() {
        std::cout << "Base default implementation" << std::endl;
    }
};

3. CRTP的常見應(yīng)用

應(yīng)用1:靜態(tài)多態(tài)(編譯期多態(tài))

template<typename Derived>
class Shape {
public:
    void draw() const {
        // 編譯期調(diào)用派生類的具體實現(xiàn)
        static_cast<const Derived*>(this)->draw_impl();
    }
    
    double area() const {
        return static_cast<const Derived*>(this)->area_impl();
    }
};

class Circle : public Shape<Circle> {
private:
    double radius;
    
public:
    Circle(double r) : radius(r) {}
    
    // 實現(xiàn)基類期望的方法
    void draw_impl() const {
        std::cout << "Drawing Circle with radius " << radius << std::endl;
    }
    
    double area_impl() const {
        return 3.14159 * radius * radius;
    }
};

class Square : public Shape<Square> {
private:
    double side;
    
public:
    Square(double s) : side(s) {}
    
    void draw_impl() const {
        std::cout << "Drawing Square with side " << side << std::endl;
    }
    
    double area_impl() const {
        return side * side;
    }
};

// 使用
template<typename T>
void processShape(const Shape<T>& shape) {
    shape.draw();
    std::cout << "Area: " << shape.area() << std::endl;
}

int main() {
    Circle circle(5.0);
    Square square(4.0);
    
    processShape(circle);  // 編譯時生成Circle版本
    processShape(square);  // 編譯時生成Square版本
}

應(yīng)用2:計數(shù)器模式

// 統(tǒng)計某個類創(chuàng)建的對象數(shù)量
template<typename T>
class Counter {
protected:
    Counter() { ++count; }
    Counter(const Counter&) { ++count; }
    Counter(Counter&&) { ++count; }
    ~Counter() { --count; }
    
public:
    static int getCount() { return count; }
    
private:
    static int count;
};

// 靜態(tài)成員初始化
template<typename T>
int Counter<T>::count = 0;

// 使用
class MyClass1 : public Counter<MyClass1> {
    // ...
};

class MyClass2 : public Counter<MyClass2> {
    // ...
};

int main() {
    MyClass1 a, b, c;
    MyClass2 x, y;
    
    std::cout << "MyClass1 count: " << MyClass1::getCount() << std::endl;  // 3
    std::cout << "MyClass2 count: " << MyClass2::getCount() << std::endl;  // 2
    // 注意:每個Counter實例都有自己的靜態(tài)count
}

應(yīng)用3:多態(tài)拷貝(虛擬構(gòu)造函數(shù))

template<typename Derived>
class Cloneable {
public:
    // 虛擬構(gòu)造函數(shù)模式
    Derived* clone() const {
        return new Derived(static_cast<const Derived&>(*this));
    }
    
protected:
    // 防止直接實例化
    Cloneable() = default;
    ~Cloneable() = default;
};

class ConcreteClass : public Cloneable<ConcreteClass> {
public:
    int value;
    
    ConcreteClass(int v) : value(v) {}
    
    // 自動獲得clone()方法
    // 可以調(diào)用clone()來創(chuàng)建副本
};

int main() {
    ConcreteClass obj1(42);
    ConcreteClass* obj2 = obj1.clone();
    
    std::cout << obj2->value << std::endl;  // 42
    
    delete obj2;
}

應(yīng)用4:靜態(tài)接口檢查

// 混入模式:為類添加功能
template<typename Derived>
class Comparable {
public:
    bool operator==(const Derived& other) const {
        return !(static_cast<const Derived&>(*this) < other) &&
               !(other < static_cast<const Derived&>(*this));
    }
    
    bool operator!=(const Derived& other) const {
        return !(*this == other);
    }
    
    bool operator<=(const Derived& other) const {
        return !(other < static_cast<const Derived&>(*this));
    }
    
    bool operator>=(const Derived& other) const {
        return !(static_cast<const Derived&>(*this) < other);
    }
    
    bool operator>(const Derived& other) const {
        return other < static_cast<const Derived&>(*this);
    }
};

// 只需要實現(xiàn)operator<,自動獲得所有比較操作
class MyInt : public Comparable<MyInt> {
public:
    int value;
    
    MyInt(int v) : value(v) {}
    
    bool operator<(const MyInt& other) const {
        return value < other.value;
    }
};

int main() {
    MyInt a(10), b(20), c(10);
    
    std::cout << std::boolalpha;
    std::cout << (a < b) << std::endl;   // true
    std::cout << (a == b) << std::endl;  // false
    std::cout << (a == c) << std::endl;  // true
    std::cout << (a != b) << std::endl;  // true
    std::cout << (a <= c) << std::endl;  // true
}

4. CRTP的高級用法

訪問派生類成員

template<typename Derived>
class AccessDerived {
public:
    void printInfo() {
        Derived* derived = static_cast<Derived*>(this);
        
        // 訪問派生類的protected成員
        std::cout << "Value: " << derived->value << std::endl;
        
        // 調(diào)用派生類的protected方法
        derived->protectedMethod();
    }
    
protected:
    // 基類可以提供一些默認實現(xiàn)
    virtual void protectedMethod() {
        std::cout << "Base protected method" << std::endl;
    }
};

class MyDerived : public AccessDerived<MyDerived> {
    friend class AccessDerived<MyDerived>;  // 允許基類訪問protected成員
    
protected:
    int value = 42;
    
    void protectedMethod() override {
        std::cout << "Derived protected method" << std::endl;
    }
};
多級CRTP
template<typename Derived>
class Level1 {
public:
    void level1Method() {
        std::cout << "Level1 calling: ";
        static_cast<Derived*>(this)->implement();
    }
};

template<typename Derived>
class Level2 : public Level1<Derived> {
public:
    void level2Method() {
        std::cout << "Level2 calling: ";
        static_cast<Derived*>(this)->implement();
    }
};

class FinalClass : public Level2<FinalClass> {
public:
    void implement() {
        std::cout << "FinalClass implementation" << std::endl;
    }
};

CRTP + 策略模式

// 策略接口
template<typename T>
class SerializationStrategy {
public:
    std::string serialize(const T& obj) const {
        return static_cast<const T*>(this)->serializeImpl();
    }
};

// 具體策略
class JSONSerialization : public SerializationStrategy<JSONSerialization> {
public:
    std::string serializeImpl() const {
        return "{ \"type\": \"json\" }";
    }
};

class XMLSerialization : public SerializationStrategy<XMLSerialization> {
public:
    std::string serializeImpl() const {
        return "<type>xml</type>";
    }
};

// 使用策略的類
template<typename SerializationStrategy>
class DataProcessor {
private:
    SerializationStrategy serializer;
    
public:
    std::string process() {
        return serializer.serialize(serializer);
    }
};

6. CRTP的最佳實踐

實踐1:使用類型檢查

template<typename Derived>
class Base {
    // 編譯時檢查:確保Derived是從Base<Derived>派生的
    static_assert(std::is_base_of<Base<Derived>, Derived>::value,
                  "Derived must inherit from Base<Derived>");
    
    // C++17的更簡潔寫法
    static_assert(std::is_base_of_v<Base, Derived>);
};

實踐2:保護構(gòu)造函數(shù)

template<typename Derived>
class Base {
protected:
    // 防止直接實例化Base
    Base() = default;
    ~Base() = default;
    
    // 防止在堆上創(chuàng)建Base
    void* operator new(std::size_t) = delete;
    void operator delete(void*) = delete;
};

實踐3:使用CRTP實現(xiàn)Mixin

// Mixin:為類添加功能
template<template<typename> class... Mixins>
class MixedClass : public Mixins<MixedClass<Mixins...>>... {
    // 繼承多個Mixin
};

// 定義Mixin
template<typename Derived>
class Printable {
public:
    void print() const {
        std::cout << "Printing..." << std::endl;
    }
};

template<typename Derived>
class Serializable {
public:
    std::string serialize() const {
        return "Serialized";
    }
};

// 使用
using MyClass = MixedClass<Printable, Serializable>;

7. CRTP在實際項目中的應(yīng)用

示例:數(shù)學(xué)向量庫

template<typename Derived, typename T>
class VectorExpression {
public:
    size_t size() const {
        return static_cast<const Derived*>(this)->size();
    }
    
    T operator[](size_t i) const {
        return static_cast<const Derived*>(this)->operator[](i);
    }
    
    // 延遲計算:表達式模板
    Derived& operator+=(const VectorExpression& other) {
        Derived& self = *static_cast<Derived*>(this);
        for (size_t i = 0; i < size(); ++i) {
            self[i] += other[i];
        }
        return self;
    }
};

template<typename T>
class Vector : public VectorExpression<Vector<T>, T> {
private:
    std::vector<T> data;
    
public:
    Vector(size_t n, T val = T{}) : data(n, val) {}
    
    size_t size() const { return data.size(); }
    
    T operator[](size_t i) const { return data[i]; }
    T& operator[](size_t i) { return data[i]; }
    
    // 允許從任何VectorExpression構(gòu)造
    template<typename E>
    Vector(const VectorExpression<E, T>& expr) : data(expr.size()) {
        for (size_t i = 0; i < expr.size(); ++i) {
            data[i] = expr[i];
        }
    }
};

8. CRTP的局限性

  • 編譯時綁定:不能在運行時改變行為
  • 代碼膨脹:每個模板實例都會生成新代碼
  • 復(fù)雜的錯誤信息:模板錯誤信息難以理解
  • 無法處理異質(zhì)集合:需要知道具體類型
  • 循環(huán)依賴:基類需要知道派生類的完整定義

9. 何時使用CRTP

適合使用CRTP的情況:

  • 需要靜態(tài)多態(tài)(性能關(guān)鍵)
  • 實現(xiàn)混入(Mixin)功能
  • 編譯期策略選擇
  • 為類族添加通用功能
  • 表達式模板

不適合使用CRTP的情況:

  • 需要運行時多態(tài)
  • 類型在運行時確定
  • 需要存儲異質(zhì)對象的容器
  • 項目對二進制大小敏感

總結(jié)

CRTP是C++模板元編程中的強大工具,它通過編譯期多態(tài)提供了零開銷的抽象能力。雖然學(xué)習(xí)曲線較陡,但在性能敏感的場景下,CRTP可以替代虛函數(shù),提供更好的運行時性能。
記住CRTP的核心思想:基類通過static_cast將this指針轉(zhuǎn)換為派生類指針,從而調(diào)用派生類的方法,所有這一切都在編譯期完成。

到此這篇關(guān)于c++ CRTP模式的使用小結(jié)的文章就介紹到這了,更多相關(guān)c++ CRTP模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • C++ 輸入scanf()和輸出printf()的操作

    C++ 輸入scanf()和輸出printf()的操作

    這篇文章主要介紹了C++ 輸入scanf()和輸出printf()的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • C語言中結(jié)構(gòu)體(struct)的幾種初始化方法

    C語言中結(jié)構(gòu)體(struct)的幾種初始化方法

    相信大家都知道struct結(jié)構(gòu)體是C語言中非常重要的復(fù)合類型,初始化的方法很多,那么小編下面對這些方法進行總結(jié),便于自己和大家以后查閱,有需要的可以參考借鑒。
    2016-08-08
  • C++設(shè)計模式編程中Template Method模板方法模式的運用

    C++設(shè)計模式編程中Template Method模板方法模式的運用

    這篇文章主要介紹了C++設(shè)計模式編程中Template Method模板方法模式的運用,講到了包括模板方法模式中的細分方法以及適用場景,需要的朋友可以參考下
    2016-03-03
  • C++ override關(guān)鍵字使用詳解

    C++ override關(guān)鍵字使用詳解

    這篇文章主要介紹了C++ override關(guān)鍵字使用詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 基于C++和MFC開發(fā)象棋程序

    基于C++和MFC開發(fā)象棋程序

    這篇文章主要為大家詳細介紹了基于C++和MFC開發(fā)象棋程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • C++中inline用法案例詳解

    C++中inline用法案例詳解

    這篇文章主要介紹了C++中inline用法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • 一文詳解C語言char類型中的存儲

    一文詳解C語言char類型中的存儲

    C語言中的char是用于聲明單個字符的關(guān)鍵字,這篇文章主要給大家介紹了關(guān)于C語言char類型中存儲的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • C++Zip壓縮解壓縮示例(支持遞歸壓縮)

    C++Zip壓縮解壓縮示例(支持遞歸壓縮)

    C++Zip壓縮解壓縮示例,用第三方函數(shù)封裝而成,支持 UNCODE, ANSCII、支持壓縮文件夾、支持遞歸壓縮
    2013-11-11
  • C與C++ 無參函數(shù)的區(qū)別解析

    C與C++ 無參函數(shù)的區(qū)別解析

    在《C++ 編程思想》:“關(guān)于無參函數(shù)聲明,C與C++有很大的差別。在C語言中,聲明int fun1(),意味著一個可以有任意數(shù)目和類型的函數(shù);而在C++中,指的卻是一個沒有參數(shù)的函數(shù)”
    2013-07-07
  • 仿現(xiàn)代C++智能指針實現(xiàn)引用計數(shù)

    仿現(xiàn)代C++智能指針實現(xiàn)引用計數(shù)

    這篇文章主要為大家詳細介紹了如何仿現(xiàn)代C++智能指針實現(xiàn)引用計數(shù),文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以了解下
    2024-03-03

最新評論

文成县| 商丘市| 孝昌县| 射阳县| 城固县| 亳州市| 全州县| 长武县| 新源县| 永济市| 乡宁县| 青浦区| 清远市| 淳化县| 色达县| 祁连县| 斗六市| 石柱| 邳州市| 建平县| 桐城市| 颍上县| 余江县| 东乡县| 无棣县| 上虞市| 迁西县| 旬阳县| 盈江县| 岑溪市| 登封市| 故城县| 保亭| 宝丰县| 黄浦区| 平乡县| 竹溪县| 阿巴嘎旗| 原平市| 蒙阴县| 开鲁县|