Skip to content

Instantly share code, notes, and snippets.

@cloudwu
Last active July 3, 2017 10:51
Show Gist options
  • Save cloudwu/0e530864e5dcb77021fb9dd550390e84 to your computer and use it in GitHub Desktop.
Save cloudwu/0e530864e5dcb77021fb9dd550390e84 to your computer and use it in GitHub Desktop.
My version of pimpl
// My version of pimpl (cloudwu@gmail.com)
// See http://en.cppreference.com/w/cpp/language/pimpl
#include <iostream>
// interface (widget.h)
class widget {
struct impl;
public:
static widget* create(int); // replacement of new
void release() const; // replacement of delete
void draw() const; // public API that will be forwarded to the implementation
void draw();
bool shown() const { return true; } // public API that implementation has to call
};
// implementation (widget.cpp)
#define DESC_SELF impl * self = static_cast<impl *>(this);
#define CONST_SELF const impl * self = static_cast<const impl *>(this);
struct widget::impl : widget {
int n; // private data
impl(int n) : n(n) {}
};
widget * widget::create(int n) {
return new impl(n);
}
void widget::release() const {
CONST_SELF
delete self;
}
void widget::draw() const {
CONST_SELF
if(self->shown()) { // this call to public member function requires the back-reference
std::cout << "drawing a const widget " << self->n << '\n';
}
}
void widget::draw() {
DESC_SELF
if(self->shown()) {
std::cout << "drawing a non-const widget " << self->n << '\n';
}
}
// user (main.cpp)
int main()
{
widget *w = widget::create(7);
const widget *w2 = widget::create(8);
w->draw();
w2->draw();
w->release();
w2->release();
}
@cupen
Copy link

cupen commented Jun 14, 2017

强势围观!

@cywu88
Copy link

cywu88 commented Jun 14, 2017

火钳留名

@DeanHH
Copy link

DeanHH commented Jun 14, 2017

火钳刘明

@Cabriter
Copy link

666

@korialuo
Copy link

广告位招租。。

@daghlny
Copy link

daghlny commented Jun 14, 2017

@solicomo
Copy link

solicomo commented Jun 14, 2017

这种方式没有借助构造及析构函数进行资源管理。
另外,这种方式应该采取措施禁止通过构造函数来创建对象,否则会出问题。

@FrankHB
Copy link

FrankHB commented Jun 16, 2017

一个pImpl也好意思没事搞个create/release,直接返回基类裸指针还敢没final/virtual/= delete,强无敌。

@fooofei
Copy link

fooofei commented Jun 17, 2017

Why change struct impl; to class impl; will cause error :
cannot cast 'widget::impl' to its private base class 'widget' ?

@fooofei
Copy link

fooofei commented Jun 17, 2017

Oh, I see, I should add public before the inherit of widget, code like this class widget::impl : public widget.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment