jason.cipriani@gmail.com
12/7/2008 4:48:00 AM
On Dec 6, 8:07 pm, "Daniel T." <danie...@earthlink.net> wrote:
> In article
> <559b868f-165e-407e-8001-9e01a575e...@v13g2000yqm.googlegroups.com>,
>
>
>
> "jason.cipri...@gmail.com" <jason.cipri...@gmail.com> wrote:
> > On Dec 6, 4:33 pm, "jason.cipri...@gmail.com"
> > <jason.cipri...@gmail.com> wrote:
> > > I'm writing a class where I want to keep a few details out of the
> > > public header, but those details are only a small fraction of
> > > everything in the class.
>
> > > Normally I'd do this with pimpl or something, but I want to avoid the
> > > inconvenience of coding and maintaining the entire pimpl abstraction.
> > > I always get uncomfortable when I try a new design pattern though. My
> > > question is: Is something like the example below in poor form? Is
> > > there a better way?
>
> > > So, say I originally have a class like this:
>
> > > class MyClass {
> > > public:
> > > MyClass ();
> > > ~MyClass ();
> > > void a ();
> > > void b ();
> > > void c ();
> > > void d ();
> > > private:
> > > int x_;
> > > int y_;
>
> > > };
>
> > > And I only want to separate part of it. So I do this (I've inlined
> > > function definitions to keep the example brief but note that, of
> > > course, the actual source code is split into appropriate headers and
> > > source files):
>
> > > class MyClass {
> > > public:
> > > MyClass () { impl_ = new MyClassPartialImpl(this); }
> > > ~MyClass () { delete impl_; }
> > > void a ();
> > > void b ();
> > > void c () { impl_->c(); }
> > > void d () { impl_->d(); }
> > > private:
> > > int x_;
> > > friend MyClassPartialImpl;
> > > MyClassPartialImpl *impl_;
>
> > > };
>
> > > class MyClassPartialImpl {
> > > public:
> > > explicit MyClassPartialImpl (MyClass *owner) : owner_(owner) { }
> > > ~MyClassPartialImpl ();
> > > void c ();
> > > void d ();
> > > private:
> > > MyClass *owner_;
> > > int y_;
>
> > Stick a "friend MyClass;" here; both MyClass::a() and MyClass::b()
> > would have access to the "hidden" things in MyClassPartialImpl (e.g.
> > y_, or any private functions).
>
> I wouldn't bother with friends:
>
> class MyClass {
> public:
> MyClass();
> ~ MyClass();
> MyClass(const MyClass& that); // note you need these
> void operator=(MyClass that);
> void c();
> private:
> int x;
> struct Impl;
> Impl* pimpl;
>
> };
>
> // in cpp file
>
> struct MyClass::Impl
> {
> Impl():y(0) { }
> int y;
>
> };
>
> MyClass(): x(0), pimpl(new Impl)
> {
>
> }
>
> MyClass::~MyClass() {
> delete pimpl;
>
> }
>
> MyClass::MyClass(const MyClass& that)
> : x(that.x)
> , pimpl( new Impl( *that.pimpl ) )
> {
>
> }
>
> void MyClass::operator=(MyClass that)
> {
> x = that.x;
> Impl* tmp = that.pimpl;
> that.pimpl = pimpl;
> pimpl = tmp;
>
> }
>
> void MyClass::c() {
> pimpl->y = 4;
> x = 8;
>
> }
>
>
I see what you mean, thanks for the tip. I like that better too. I
guess it's not actually that unusual, I called it "pimpl" but really
it's just a class with a pointer to another class as a member
variable, nothing special.
Thanks,
Jason