软件开发的重复模板模式(CRTP)

通过软件开发奇怪的重复模板模式(CRTP)可以完全避免使用VPtr和VTable。CRTP是C ++中的一种设计模式,其中类X派生自使用X本身作为模板参数的类模板实例化。更一般地,它被称为F结合多态性。
filter_none
编辑
play_arrow
 
brightness_4
// Image program (similar to above) to demonstrate 
// working of CRTP 
#include <iostream> 
#include <chrono> 
using namespace std; 
  
typedef std::chrono::high_resolution_clock Clock; 
  
// To store dimensions of an image 
class Dimension 
public: 
    Dimension(int _X, int _Y) 
    { 
        mX = _X; 
        mY = _Y; 
    } 
private: 
    int mX, mY; 
}; 
  
// Base class for all image types. The template 
// parameter T is used to know type of derived 
// class pointed by pointer. 
template <class T> 
class Image 
public: 
    void Draw() 
    { 
        // Dispatch call to exact type 
        static_cast<T*> (this)->Draw(); 
    } 
    Dimension GetDimensionInPixels() 
    { 
        // Dispatch call to exact type 
        static_cast<T*> (this)->GetDimensionInPixels(); 
    } 
  
protected: 
    int dimensionX, dimensionY; 
}; 
  
  
// For Tiff Images 
class TiffImage : public Image<TiffImage> 
public: 
    void Draw() 
    { 
        // Uncomment this to check method dispatch 
        // cout << "TiffImage::Draw() called" << endl; 
    } 
    Dimension GetDimensionInPixels() 
    { 
        return Dimension(dimensionX, dimensionY); 
    } 
}; 
  
// There can be more derived classes like PngImage, 
// BitmapImage, etc 
  
// Driver code 
int main() 
    // An Image type pointer pointing to Tiffimage 
    Image<TiffImage>* pImage = new TiffImage; 
  
    // Store time before virtual function calls 
    auto then = Clock::now(); 
  
    // Call Draw 1000 times to make sure performance 
    // is visible 
    for (int i = 0; i < 1000; ++i) 
        pImage->Draw(); 
  
    // Store time after virtual function calls 
    auto now = Clock::now(); 
  
    cout << "Time taken: "
         << std::chrono::duration_cast 
         <std::chrono::nanoseconds>(now - then).count() 
         << " nanoseconds" << endl; 
  
    return 0; 
输出:
 
所用时间:732纳秒
见这对上述结果。
 
虚拟方法与CRTP基准测试
使用虚拟方法所用的时间为2613纳秒。CRTP的这种(小)性能增益是因为绕过了VTable调度的使用。请注意,性能取决于许多因素,如使用的编译器,虚拟方法执行的操作。不同运行中的性能数字可能不同,但CRTP预计会有(小)性能提升。
注意:如果我们在CRTP中打印类的大小,可以看出VPtr不再保留4个字节的内存。
 
 
cout << sizeof(图片)<< endl; 
 
18215660330
179001057@qq.com