pimpl+模板函数
header
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <memory> // interface (widget.h) class widget { class impl; std::unique_ptr<impl> pImpl; public: void draw() const; // public API that will be forwarded to the implementation template<typename T> void draw() { _draw(); } void _draw(); bool shown() const { return true; } // public API that implementation has to call widget(int); ~widget(); // defined in the implementation file, where impl is a complete type widget(widget&&); // defined in the implementation file // Note: calling draw() on moved-from object is UB widget(const widget&) = delete; widget& operator=(widget&&); // defined in the implementation file widget& operator=(const widget&) = delete; };
impl cpp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include "impl.h" #include <iostream> #include <iomanip> #include <memory> template<typename T, typename... Args> std::unique_ptr<T> make_unique(Args&&... args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } // implementation (widget.cpp) class widget::impl { int n; // private data public: void draw(const widget& w) const { if(w.shown()) // this call to public member function requires the back-reference std::cout << "drawing a const widget " << n << '\n'; } void draw(const widget& w) { if(w.shown()) std::cout << "drawing a non-const widget " << n << '\n'; } // void draw() { // std::cout << "drawing a non-const widget " << n << '\n'; // } impl(int n) : n(n) {} }; void widget::draw() const { pImpl->draw(*this); } void widget::_draw() { pImpl->draw(*this); } widget::widget(int n) : pImpl{make_unique<impl>(n)} {} widget::widget(widget&&) = default; widget::~widget() = default; widget& widget::operator=(widget&&) = default;
main
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include "impl.h" #include <iostream> #include <vector> int main() { widget w(7); const widget w2(8); w.draw(); w2.draw(); }
pimpl也可应用在模板类中,将与模板无关的代码提取到基类,在基类中做pimpl。