通过软件开发奇怪的重复模板模式(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