Article View: comp.std.c++
Article #4095Re: methods for accessing attributes
From: John A Hughes
Date: Thu, 18 Apr 1996 00:44
Date: Thu, 18 Apr 1996 00:44
94 lines
3805 bytes
3805 bytes
In article <9604160147.AA25931@grace>,
Steve Clamage <clamage@taumet.eng.sun.com> wrote:
[I don't think this was really Steve Clamage, but that's what my
newsreader said!!]
>If lots of code already exists like the following:
>
> void blah(Display &d)
> {
> d.wid = 80;
> }
>
>And now suppose that we want Display to do something when
>the width is changed--- has there been any consideration of adding
>a way of doing this? (besides changing all the direct accesses
>to function calls)
>Or is there some way, within the current standard, to do this?
>I toyed with some ways that involved replacing the type of 'wid'
>(int) with some class that did the desired operation when assigned to,
>but in order to have full access to Display, it has to be a specialized
>class for each instance variable, and each class has to have special
>code containing knowledge of the offset of 'wid' within 'Display'
>and then it has to use that offset along with some really evil
>casting to find the address of the 'Display' object it resides in.
No, not necessarily. For the exact case you showed in your post, you
could have a class like this, though it wouldn't solve all your
problems:
template<class MainClass, class MemberClass>
class SmartMember {
public:
SmartMember(MainClass &o, void(*MainClass::f)(MemberClass))
: main_obj(o), change_fn(f) {}
SmartMember &operator=(MemberClass t) {
main_obj.change_fn(t);
}
operator T() {return datum;}
private:
MainClass &main_obj;
MemberClass datum;
void(*MainClass::change_fn)(MemberClass);
};
So now your class Display looks something like this:
class Display {
public:
Display(...);
SmartMember<Display,int> wid;
//...
private:
void updateWid(int new_wid);
//...
};
and you'll need to make sure your Display constructors do the following:
Display::Display(...) : wid(*this, &Display::updateWid) {
//...
}
which means that wid now knows it's a member of the given display and that
when it changes it should change via updateWid.
Now you can leave all your
void blah(Display &d)
{
d.wid = 80;
}
as they are. The SmartMember class is generic so you can do it for
every kind of member of every kind of class that has assignment
semantics.
I suspect defining this one class and changing a couple constructors
is easier than changing all your assignments, but then again, it's
weird and I only suggested it to show that you COULD do it without
changing all your assignment statements or defining a class for every
type. This won't work at all if you ever pass wid by reference and
expect changes to happen that way. You should have known better than
to make your member data public in the first place, and rewriting it
is probably the RIGHT thing to do.
Have fun
jah
---
[ comp.std.c++ is moderated. To submit articles: try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Technical Details
Message-ID:
<4l0k0e$329@news2.cais.com>Path:
arc1-ca.pugleaf.net!in2.uu.net!bounce-backReferences:
<9604160147.AA25931@grace>Show Full Headers
Complete Article Headers
From: jah@cais.cais.com (John A Hughes) Message-ID: <4l0k0e$329@news2.cais.com> X-Original-Date: 16 Apr 1996 17:05:18 GMT Path: arc1-ca.pugleaf.net!in2.uu.net!bounce-back Date: 18 Apr 96 00:44:51 GMT Approved: fjh@cs.mu.oz.au Newsgroups: comp.std.c++ Subject: Re: methods for accessing attributes Organization: Capital Area Internet Service info@cais.com 703-448-4470 References: <9604160147.AA25931@grace> X-Auth: PGPMoose V1.1 PGP comp.std.c++ iQBFAgUBMXWQ1uEDnX0m9pzZAQFPLQF8Du8J7REeSXZMxTESKpdJLnwyRMa74w72 UcprIMj7oIGQFX+FMl6IhUMdNUD0hKr+ =s/5R