本文為 C++ Software Design 書的第 33 節內容。
class Shape {
public:
template <typename ShapeT, typename DrawStrategy>
Shape(ShapeT shape, DrawStrategy drawer)
: pimpl_(new OwningModel(std::move(shape), std::move(Drawer)),
[](void* shapeBytes){
using Model = OwningModel<ShapeT,DrawStrategy>;
auto* const model = static_cast<Model*>(shapeBytes);
delete model;
})
, draw_([](void* shapeBytes) {
using Model = OwningModel<ShapeT,DrawStrategy>;
auto* const model = static_cast<Model*>(shapeBytes);
(*model->drawer_)(model->shape_);
})
, clone_([](void* shapeBytes) {
using Model = OwningModel<ShapeT,DrawStrategy>;
auto* const model = static_cast<Model*>(shapeBytes);
return new Model(*model);
})
{}
private:
template <typename ShapeT, typename DrawStrategy>
struct OwningModel {
OwningModel(ShapeT value, DrawStrategy drawer)
: shape_(std::move(value))
, drawer_(std::move(drawer)) {}
ShapeT shape_;
DrawStrategy drawer_;
};
using DestroyOp = void(void*);
using DrawOp = void(void*);
using CloneOp = void*(void*);
std::unique_ptr<void,DestroyOp*> pimpl_;
DrawOp* draw_;
CloneOp* clone_;
};
主要的細節為將 virtual function 轉化成 void* 的函數,再用 static_cast 轉型成 OwningModel 的類別。根據書中的實驗結果,使用此技巧後大概能將效能提高 25%。