473,396 Members | 2,011 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Naming convention for accessor methods (get/set)

A lot has been said in this newsgroup regarding the "evil" set/get
accessor methods. Arthur Riel, (of Vanguard Training), in his class,
"Heuristis for O-O Analysis & Design", says that there is almost never
an excuse for accessor methods. Personally, I do not go that far. I
do feel that they serve a useful purpose (albeit in a limited manner).
Personally I prefer dropping the "set" and "get" prefixes from the
method names altogether. For example:

class A
{
public:
...
int xyz() { return _xyz; } // instead of get_xyz()
void xyz(const int val) { _xyz = val; } // instead of get_xyz()
...

protected:
...
int _xyz;
...
};
This naming convention is also consistent with the IDL/C++ language
binding, and I wanted to seek your opinion regarding this.

Regards,
KP Bhat

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #1
22 11990
Generic Usenet Account wrote:
A lot has been said in this newsgroup regarding the "evil" set/get
accessor methods. Arthur Riel, (of Vanguard Training), in his class,
"Heuristis for O-O Analysis & Design", says that there is almost never
an excuse for accessor methods. Personally, I do not go that far. I
do feel that they serve a useful purpose (albeit in a limited manner).
Personally I prefer dropping the "set" and "get" prefixes from the
method names altogether. For example:

class A
{
public:
...
int xyz() { return _xyz; } // instead of get_xyz()
void xyz(const int val) { _xyz = val; } // instead of get_xyz()
...

protected:
...
int _xyz;
...
};
This naming convention is also consistent with the IDL/C++ language
binding, and I wanted to seek your opinion regarding this.


(Cross-post to comp.lang.c++.moderated removed. Cross-posting to
moderated groups slows down responses.)

My opinion:

I don't see a real problem with your naming scheme, but I wouldn't use
it personally. Overloaded functions are generally used when multiple
functions perform the same (or a similar) task using different
arguments. In this case, the functions do rather different things, so I
would prefer different names.

Set/get member functions aren't inherently bad, but some beginners get
the idea that they are a standard part of every class, which is
completely wrong. Most classes shouldn't have a need for typical set and
get functions (those that correspond to the actual data members in the
class). The interface should be separate from the representation
(obviously) so except in rather simple cases, you can't expect a
well-designed interface to correspond to the members used to represent
the class's state.

One last thing, I would recommend not using names that begin with an
underscore. It's OK in the context above, but there's a lot of cases
where it's not. The easiest way to avoid problems is to get in the habit
of never using identifiers (macros, variables, etc.) that begin with an
underscore.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Jul 19 '05 #2
Kevin Goodsell wrote:
Generic Usenet Account wrote: .... (Cross-post to comp.lang.c++.moderated removed. Cross-posting to
moderated groups slows down responses.)

My opinion:

I don't see a real problem with your naming scheme, but I wouldn't use
it personally. Overloaded functions are generally used when multiple
functions perform the same (or a similar) task using different
arguments. In this case, the functions do rather different things, so I
would prefer different names.

Set/get member functions aren't inherently bad, but some beginners get
the idea that they are a standard part of every class, which is
completely wrong. Most classes shouldn't have a need for typical set and
get functions (those that correspond to the actual data members in the
class). The interface should be separate from the representation
(obviously) so except in rather simple cases, you can't expect a
well-designed interface to correspond to the members used to represent
the class's state.

One last thing, I would recommend not using names that begin with an
underscore. It's OK in the context above, but there's a lot of cases
where it's not. The easiest way to avoid problems is to get in the habit
of never using identifiers (macros, variables, etc.) that begin with an
underscore.


Opinion seconded.

Jul 19 '05 #3
le Friday 19 September 2003 13:08, us****@sta.samsung.com écrivit :
int xyz() { return _xyz; } // instead of get_xyz()
void xyz(const int val) { _xyz = val; } // instead of get_xyz()


There is one small factual inconvienence I can think of.
While you can do :

vector<A> v;
int x;
for_each(v.begin(), v.end(), bind2nd(mem_fun_ref(&A::set_xyz), x) );

You need specific code to reach the overloaded 'xyz' membre function :

void (A::* pmf)(const int) = &A::xyz;
for_each(v.begin(), v.end(), bind2nd(mem_fun_ref(pmf), x) );
oh, and it's easier to search for 'set_xyz' in a file. (the overloaded one
can be searched using a regexp like 'xyz([^)]*)' , it's not too complicated
either)

except for those details, I think it does'nt make much of a difference.

--
Samuel.Krempp
cout << "@" << "crans." << (is_spam ? "trucs.en.trop." : "" )
<< "ens-cachan.fr" << endl;
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #4
Gianni Mariani <gi*******@mariani.ws> wrote in message news:<bk********@dispatch.concentric.net>...
Kevin Goodsell wrote:
One last thing, I would recommend not using names that begin with an
underscore. It's OK in the context above, but there's a lot of cases
where it's not. The easiest way to avoid problems is to get in the habit
of never using identifiers (macros, variables, etc.) that begin with an
underscore.


Opinion seconded.


How about ending with underscore?

-Chaud Lapin-
Jul 19 '05 #5
Le Chaud Lapin wrote:
Gianni Mariani <gi*******@mariani.ws> wrote in message news:<bk********@dispatch.concentric.net>...
Kevin Goodsell wrote:
One last thing, I would recommend not using names that begin with an
underscore. It's OK in the context above, but there's a lot of cases
where it's not. The easiest way to avoid problems is to get in the habit
of never using identifiers (macros, variables, etc.) that begin with an
underscore.


Opinion seconded.

How about ending with underscore?


That's fine as long as it's not immediately preceded by another
underscore. Identifiers containing a sequence of two underscores are
also reserved (though I don't know what for off the top of my head). So
this:

identifier_

is OK. These are not:

_identifier (well, it's OK in some places)
_Identifier (pretty much never OK)
_IDENTIFIER (also never OK)
identifier__
__identifier
foo__bar

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Jul 19 '05 #6
Generic Usenet Account escribió:
Personally I prefer dropping the "set" and "get" prefixes from the
method names altogether. For example:
(snip)
This naming convention is also consistent with the IDL/C++ language
binding, and I wanted to seek your opinion regarding this.


In Spain we say: "aunque la mona se vista de seda, mona se queda". "A
monkey is a monkey even if dressed in silk" can be a translation. It is
the same thing wheter you use or not set and get prefixes. Personal
preference, as you say.

Regards.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #7
How about:

class A {
public:
int& EVIL() { return _evil; }
const int& EVIL() const { return _evil; }
};

This really is a horrible design... because you are exposing the underlying
implementation of your class. Which implies that if the implementation
changes, then the interface may need to be changed as well. That is more
evil than Sadam, Bin Laden, Stalin and Hitler put together. If you need to
be able to create setters and getters, why not just make the variable
public. If you need to have some other unrelated class access
private/protected elements of some other class, use friends instead. At
least you will not be breaking encapsulation.

GRRR

Martin
"Generic Usenet Account" <us****@sta.samsung.com> wrote in message
news:90************************@posting.google.com ...
A lot has been said in this newsgroup regarding the "evil" set/get
accessor methods. Arthur Riel, (of Vanguard Training), in his class,
"Heuristis for O-O Analysis & Design", says that there is almost never
an excuse for accessor methods. Personally, I do not go that far. I
do feel that they serve a useful purpose (albeit in a limited manner).
Personally I prefer dropping the "set" and "get" prefixes from the
method names altogether. For example:

class A
{
public:
...
int xyz() { return _xyz; } // instead of get_xyz()
void xyz(const int val) { _xyz = val; } // instead of get_xyz()
...

protected:
...
int _xyz;
...
};
This naming convention is also consistent with the IDL/C++ language
binding, and I wanted to seek your opinion regarding this.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #8

"Generic Usenet Account" <us****@sta.samsung.com> wrote in message
news:90************************@posting.google.com ...
A lot has been said in this newsgroup regarding the "evil" set/get
accessor methods. Arthur Riel, (of Vanguard Training), in his class,
"Heuristis for O-O Analysis & Design", says that there is almost never
an excuse for accessor methods. Personally, I do not go that far. I
do feel that they serve a useful purpose (albeit in a limited manner).
Personally I prefer dropping the "set" and "get" prefixes from the
method names altogether. For example:

class A
{
public:
...
int xyz() { return _xyz; } // instead of get_xyz()
void xyz(const int val) { _xyz = val; } // instead of get_xyz()
...

protected:
...
int _xyz;
...
};
This naming convention is also consistent with the IDL/C++ language
binding, and I wanted to seek your opinion regarding this.


I also prefer to overload a single meaningful name for this.

This is typically (but not always) feasible since one usually
takes an argument and the other does not. This form has worked
well for me so far.
-Mike

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #9
apm
us****@sta.samsung.com (Generic Usenet Account) wrote in message news:<90************************@posting.google.co m>...
A lot has been said in this newsgroup regarding the "evil" set/get
accessor methods. Arthur Riel, (of Vanguard Training), in his class,
"Heuristis for O-O Analysis & Design", says that there is almost never
an excuse for accessor methods. Personally, I do not go that far. I
do feel that they serve a useful purpose (albeit in a limited manner).
Personally I prefer dropp


So do I. Here's why:

The Uniform Access Principle espoused by Betrand Meyer states that all
services offerd by a module should be available through a uniform
notation which does not betray whether they are implemented through
storage or through computation. Get get/set convention violates this.

-Andrew Marlow

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #10
In article <bk**********@uni00nw.unity.ncsu.edu>, Marcin Vorbrodt
<mv*****@eos.ncsu.edu> writes
How about:

class A {
public:
int& EVIL() { return _evil; }
const int& EVIL() const { return _evil; }
};

This really is a horrible design... because you are exposing the underlying
implementation of your class. Which implies that if the implementation
changes, then the interface may need to be changed as well. That is more
evil than Sadam, Bin Laden, Stalin and Hitler put together. If you need to
be able to create setters and getters, why not just make the variable
public. If you need to have some other unrelated class access
private/protected elements of some other class, use friends instead. At
least you will not be breaking encapsulation.


But you snuck in return by reference which is a quite different issue.
Consider the following public interface for a class:

class point2d {
public:
// constructor:
explicit point2d(double xval=0, double yval=0);
// read access functions
double x()const;
double y()const;
double modulus()const;
double argument()const;
// write access functions
point2d & x(double xval);
point2d & y(double yval);
point2d & modulus(double mod);
point2d & argument(double degrees);
private:
// data choice irrelevant

};
Note that the user has no need to know how the data locating a point on
a plane is organised. However there is a great deal of benefit from
being able to select using Cartesian or Polar co-ordinates according to
what you are doing.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #11
WW
apm wrote:
us****@sta.samsung.com (Generic Usenet Account) wrote in message
news:<90************************@posting.google.co m>...
A lot has been said in this newsgroup regarding the "evil" set/get
accessor methods. Arthur Riel, (of Vanguard Training), in his class,
"Heuristis for O-O Analysis & Design", says that there is almost
never
an excuse for accessor methods. Personally, I do not go that far. I
do feel that they serve a useful purpose (albeit in a limited
manner). Personally I prefer dropp


So do I. Here's why:

The Uniform Access Principle espoused by Betrand Meyer states that all
services offerd by a module should be available through a uniform
notation which does not betray whether they are implemented through
storage or through computation. Get get/set convention violates this.


Without going to quoting authority opinions and theories I would rather
tackle the problem from a T word point of view. A class (be it any class)
represents a concept in a problem domain. if that concept suport the
existence of things called getXxx setXxx then you should have them. If not,
you should not.

Furthermore a class is either just a representation of some simple storage
facility (in which case getters and setter might be appropriate) or it is
not. IMHO it is very very rare in real life design when you need such a
class. And if you feel you do, you really have to defend the idea, because
unless that class provides an adapter or facade to an exteranl storage
system they seem to have absolutely no function whatsoever.

Just let me give one example of a place where get/set might be appropriate
(as a name):

struct Radio {
xxx setVolume()...
xxx getVolume()...
private:
....
};

--
WW aka Attila

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #12
In article <0u******************@newsread4.news.pas.earthlink .net>,
us*********************@neverbox.com says...

[ ... ]
That's fine as long as it's not immediately preceded by another
underscore. Identifiers containing a sequence of two underscores are
also reserved (though I don't know what for off the top of my head).


Just in case you happen to really care: it's reserved because some
compilers used that as the separator between the name and the name
mangling -- this was (and may still be) particularly widely used among
compilers that produced C as output, since the result had to be a legal
C identifier.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 19 '05 #13
"Generic Usenet Account" <us****@sta.samsung.com> wrote in message news:90************************@posting.google.com ...
A lot has been said in this newsgroup regarding the "evil" set/get
accessor methods. Arthur Riel, (of Vanguard Training), in his class,
"Heuristis for O-O Analysis & Design", says that there is almost never
an excuse for accessor methods.
Accessor methods can become neccessary when you have several properties of a class which are really different views/transformations of the same underlying property. An example already given was polar vs. cartesian coordinates.

Here's another:

class P{
public:
// directory
std::string GetDirectory();
void PutDirectory(const std::string& newDir);
// filename = basename.extension
std::string GetFileName();
void PutFileName(const std::string& newFileName);
// full path
std::string GetFullPath();
void PutFullPath(const std::string& newPath);
// now add BaseName and Extension.
};

// example:
// this/is/the/directory/basename.extension
It may perfect sense to Get/Put any of these five properties independently; depending on what the program intends to do with the information. If it wants to create a sibling file, it can use GetDirectory. If it wants to name a known sibling file according to some convention, it might want to set the extension only. If it wants to name a companion file in a different folder, to set the directory, and so forth.
Personally I prefer dropping the "set" and "get" prefixes from the
method names altogether. For example:
(deleted)
This naming convention is also consistent with the IDL/C++ language
binding, and I wanted to seek your opinion regarding this.


You are talking about the CORBA IDL C++ language binding of course... as opposed to the many other IDL's, such as DCE/RPC, MIDL, MACH, Sun RPC and so forth.

It is time to invoke the concept of Least Surprise. If the code is intended or likely to be mixed with CORBA objects and calls, this would be a good convention to use. If it is intended or likely to be used together with with some other convention, you may wish to use that convention.

Personally I prefer Get/Put as prefixes, because one day you will need an indexed property.

class A{
public:
std::string GetValue(const std::string& name);
void PutValue(const std::string& name, const std::string& value);
};

Some times it is appropriate to use more than one convention:
class B{
public:
long get_Value(const std::string& name, std::string& value) throw();
long put_Value(const std::string& name, const std::string& value) throw();
std::string GetValue(const std::string& name) throw(MyException){
std::string tmp; long lErrCode = get_Value(name, tmp);
if(lErrCode)throw MyException(lErrCode);
return tmp;
}
void PutValue(const std::string& name, const std::string& value) throw(MyException){
long lErrCode = put_Value(name, value);
if(lErrCode)throw MyException(lErrCode);
}
};
This gives more flexibility to the user of the class. The verbosity and duplication involved mean that it is only really appropriate for very small or very stable libraries which are frequently used and thoroughly tested, or of course, for machine-generated code, for example from some sort of IDL.
--
Cheers,
Ben Liddicott
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #14
ap***@student.open.ac.uk (apm) writes:
The Uniform Access Principle espoused by Betrand Meyer states that
all services offerd by a module should be available through a uniform
notation which does not betray whether they are implemented through
storage or through computation. Get get/set convention violates this.


Could you explain what you mean - it seems that wrapping everything in
get_x() and set_x() would indeed hide what was stored and what was
computed (though it's not clear what it means to call set_x() if x is
a computed value).

--
Ed Avis <ed@membled.com>

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #15
I believe Stroustrup favours the style of accessor where a single
overloaded function name is used for both getting and setting.
At least, ISTR seeing such a thing in the C++ book, and didn't see
any get_x() or set_x() methods.

--
Ed Avis <ed@membled.com>
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #16
"Marcin Vorbrodt" <mv*****@eos.ncsu.edu> writes:
class A {
public:
int& EVIL() { return _evil; }
const int& EVIL() const { return _evil; }
};

This really is a horrible design... because you are exposing the underlying
implementation of your class.
It's not necessarily evil - for some concrete types it may be simplest
to expose the implementation. If a complex number has 'real' and
'imag', and you don't plan to change to polar coordinates later, you
might as well expose those rather than clutter the interface with
accessors. Especially so if you are writing this class for your own
use and can simply change all the callers in the unlikely event of the
implementation changing.

However if you are writing a class for 'complex number with magnitude
less than 1', then you wouldn't make the members public because it
would let a caller too easily break the class invariant.
If you need to be able to create setters and getters, why not just
make the variable public.


Indeed. The above code, however, may be preferred in shops where
coding standards mandate using accessors for all members and never
making them public. It's a way to simulate public visibility, in
cases where that would be the best design, while staying within the
letter of the religious law. (Of course, in such cases the accessors
would probably be called getEvil() or getMyEvil() or
pIGetMyEvilAsReference().)

--
Ed Avis <ed@membled.com>

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #17
ap***@student.open.ac.uk (apm) writes:

|> us****@sta.samsung.com (Generic Usenet Account) wrote in message news:<90************************@posting.google.co m>...

|> > A lot has been said in this newsgroup regarding the "evil" set/get
|> > accessor methods. Arthur Riel, (of Vanguard Training), in his
|> > class, "Heuristis for O-O Analysis & Design", says that there is
|> > almost never an excuse for accessor methods. Personally, I do not
|> > go that far. I do feel that they serve a useful purpose (albeit in
|> > a limited manner). Personally I prefer dropp

|> So do I. Here's why:

|> The Uniform Access Principle espoused by Betrand Meyer states that
|> all services offerd by a module should be available through a
|> uniform notation which does not betray whether they are implemented
|> through storage or through computation. Get get/set convention
|> violates this.

So do any of the alternatives in C++.

Or rather, none of them do, if used consistently. How does get and set
betray the underlying implementation?

--
James Kanze mailto:ka***@gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #18
mv*****@eos.ncsu.edu (Marcin Vorbrodt) wrote (abridged):
class A {
public:
int& EVIL() { return _evil; }
const int& EVIL() const { return _evil; }
};

This really is a horrible design... [...] If you need to be able
to create setters and getters, why not just make the variable
public.


There are degrees of encapsulation. Your interface at least allows
some indirection. For example:

int &EVIL() {
if (_pImpl == NULL)
_pImpl = new Impl;
return _pImpl->EVIL();
}

There is quite a lot of flexibility available. Eg if A has more than
one variable, we can use more than one Impl class and allocate them
at different times.

Reference-returning functions restrict the implementation less than
exposing an actual instance variable. Personally I avoid them (even
for things like vector::operator[]), but they are not evil.

-- Dave Harris, Nottingham, UK

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #19
Generic Usenet Account wrote:
A lot has been said in this newsgroup regarding the "evil" set/get
accessor methods. Arthur Riel, (of Vanguard Training), in his class,
"Heuristis for O-O Analysis & Design", says that there is almost never
an excuse for accessor methods. Personally, I do not go that far. I
do feel that they serve a useful purpose (albeit in a limited manner).
Personally I prefer dropping the "set" and "get" prefixes from the
method names altogether. For example:

class A
{
public:
...
int xyz() { return _xyz; } // instead of get_xyz()
void xyz(const int val) { _xyz = val; } // instead of get_xyz()
...

protected:
...
int _xyz;
...
};
This naming convention is also consistent with the IDL/C++ language
binding, and I wanted to seek your opinion regarding this.


I'm unsure if you are looking for opinions of if accessor functions are
a design mistake or how to name them in the rare cases where they are
useful.

For the latter I would call them getX() and setX() (or get_x...) just
for the case I have to address one of the functions as an parameter to
an ScopeGuard to rollback a prior set value back to its original value.

But if you are looking for some excuse to use accessors (especial
setters) I would tend to say that it's a design flaw in most cases. I
experienced two situations in my career by now, where setters where
useful. The first was a class that cached configuration data from a data
base by it's getters but also had setters to change the configuration.
But the setters didn't only updated the configuration into the DB but
informed other processes about the configuration changes, so the same
class linked into an other process read the configuration from the DB.
The second case where I used setters where I had to create Object as
copy from other object and to make little changes on them.

regards Torsten
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #20
> This naming convention is also consistent with the IDL/C++ language
binding, and I wanted to seek your opinion regarding this.


C++ iostreams uses the int xyz(); void xyz(int) convention as well.

What is so evil about accessors/mutators, if they are not "just"
returning the underlying data member? (They could be calculating it,
caching it or passing it on to another object for example.)

Here's a suggestion to make the accessor/mutator pair into a first
class object, akin (but better in the long run) to VB/C# property,
your thots please.

We define a property class (with appropriate templating) to declare:

property& operator= (T);
operator T() const;

The signature is the same or similar to the proxy objects that often
crop up in delayed dereferencing scenarios.

The class contains a reference to the underlying object, and two PMFs
(either as template non-type params or constructor params) to the
[private] accessor/mutators in the object.

The object can either expose the property as a public data member (I'm
going to get into trouble for this one...), or through a member
function.

The former allows you to do this:
a.xyz = 12; std::cout << a.xyz;

The latter is slightly clunkier:
a.xyz() = 12; std::cout << a.xyz();

If the latter, a compiler would probably just optimize away the
property temporary anyway. (The latter also allows indexing
scenarios.)

What else does this buy you? The property can now be used as an
object, a substitute for a reference e.g.

template <typename U> void mul (U& z, const U& x, const U& y) { z = x
* y; }

Now mul could only take U = int before. But it can now take a property
and it will do the right thing. A bit similar to how an STL iterator
is an extension of the pointer, the property is like an extension to
reference. mul would not work with the pair of accessor/mutator
unwrapped.

Any comments, caveats, thoughts on this?

Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #21
Glen Low wrote:
[snip]
Here's a suggestion to make the accessor/mutator pair into a first
class object, akin (but better in the long run) to VB/C# property,
your thots please.

We define a property class (with appropriate templating) to
declare:

property& operator= (T);
operator T() const;

The signature is the same or similar to the proxy objects that
often crop up in delayed dereferencing scenarios.

The class contains a reference to the underlying object, and two
PMFs (either as template non-type params or constructor params) to
the [private] accessor/mutators in the object.

The object can either expose the property as a public data member
(I'm going to get into trouble for this one...), or through a
member function.
Exposing a member doesn't have to constrain the enclosing class at all:

class X {
X( X const& );
X& operator = ( X const& );
void operator & () const;
// anything else I left out :)
};

class Foo {
public:
X x; // what does this expose other than Foo having an X named x?
};
What else does this buy you? The property can now be used as an
object, a substitute for a reference e.g.

template <typename U> void mul (U& z, const U& x, const U& y) { z =
x * y; }

Now mul could only take U = int before. But it can now take a
property and it will do the right thing. A bit similar to how an
STL iterator is an extension of the pointer, the property is like
an extension to reference. mul would not work with the pair of
accessor/mutator unwrapped.
With properties added to the mix, a class could be seen as a collection of
members, each with a particular interface. A data member is an entity
which stores a value and allows access to it. A member function is an
entity which has an operator () and implements it via its definition, or
via the virtual dispatch mechanism. A value property is an entity which
acts like a value but implements get and set via function call rather than
by-value storage within itself.

This value property allows accessible abstract state to be expressed more
directly, and manipulated using the already-existing mechanisms for values
(as your example shows). At the core of this is the recognition that a
class is a collection of interface elements, and we can start thinking of
expansion of the usual set.

I described this value property in a way that I hope hints at further
possibilities. One is backwards-compatibility with overloaded accessor
functions that it might have replaced: a value property can define
operator () () as a getter and operator () ( value_type ) as a setter.
There could be a "cached value property" which keeps a copy of its value
and gives this out when it is read, and when it is written, only invokes
the "set new value" callback if the new value is different than the old
one.

It's also possible to go beyond values. How about a readable boolean flag
with an optional callback that is invoked when it changes value? This
property would keep track of the current value, allow reading of this, and
allow registration of a callback function. The enclosing class would keep
this flag up-to-date, but wouldn't have to bother with the callback. The
property would have public functions and "parent-only" functions that were
only accessible to the enclosing class (here there would be a parent-only
function to change the flag's value).

How about a counted entry/exit with parent notification on first
entry/last exit? Here the property stores the entry count, has member
functions entry() and exit(), and two callbacks to the parent,
first_entry() and last_exit().

I've done a little experimentation with data providers and consumers. I
made a supplier and consumer property. It uses an intrusive circular
doubly-linked "ring" and traversed it when the provider had a new value. A
class might supply many different values, so each one could be a separate
property.

A property could be thought of as being just like a base class, except
that its interface isn't injected into the parent class but rather appears
as part of the interface of a member of the parent class. The parent class
can override "virtual" functions in the property and gets special access
like a derived class can.

Properties have two clients: general clients and the parent class. I think
of the electronics field where there are user-interface devices which have
internals and an interface to the device. Think of a simple toggle switch:
It has a button that the user can press (the public interface), two wires
which are either electrically open or closed (the parent-only interface),
and a mechanism to keep the current open/closed state latched and toggle
it when the button is pressed. Without property elements, the engineer's
equivalent would be mounting the toggle switch inside the device and
running a long mechanical bar from the button to the case (i.e. connect
the button's interface to the public via a member function).

A fine point I encountered in various implementations: with the
introduction of property values, the value type might differ from the
object type. An int stores an int, but a value_property<int> doesn't store
a value_property<int>. I solved this with a simple value_type<> type
mapping, where value_type<int>::type and value_type<value_property<int>::type both yielded int. This allowed simple scoped value restoration

which worked for any value type.

I've implemented several very crude libraries for experimentation with
properties over the years. I implemented quite a few properties in various
classes (file streams, audio output, GUI controls) but never really found
much use for them. Because I had the possibility of implementing ideas of
new properties, I was open to places to add them, but very few ideas ever
came. I'd be interested in brainstorming places where they might be
useful, then looking critically or even trying it out. I think that the
ability to do hands-on experiments is very important for growing and even
the abandoning of ideas. I have a feeling that the property idea might not
be viable, but I want to see it demonstrated. I'm not content with
reasoning it away, because most reasoning I've encountered seemed aimed at
avoiding the possibility of something new rather than making insights as
to the flaws.

--
Shay

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #22
In article <92**************************@posting.google.com >,
gl*****@pixelglow.com says...

[ ... ]
We define a property class (with appropriate templating) to declare:

property& operator= (T);
operator T() const;

The signature is the same or similar to the proxy objects that often
crop up in delayed dereferencing scenarios.
This was suggested in a rather lengthy thread years ago in comp.std.c++.
Feel free to read through the thread starting at:

http://www.google.com/groups?threadm...ocoa.brown.edu

for various views on the subject.
The object can either expose the property as a public data member (I'm
going to get into trouble for this one...), or through a member
function.


IMO, in a situation like this, the member function provides no real
capabilities to compensate for the obfuscation.

--
Later,
Jerry.

The universe is a figment of its own imagination.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #23

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

27
by: Derek | last post by:
The company where I work uses a naming convention that I have never used before. They use mixed-case letters for public member functions, but lower-case with underscores for the rest, like this:...
5
by: Ook | last post by:
Is there any kind of naming convention for accessor and modifiers? What I've been doing is something like this: // accessor int getSize(); // Modifier void setSize( int newsize); private:
4
by: Mark Broadbent | last post by:
stupid question time again to most of you experts but this is something that continually bothers me. I am trying to get into the habit of naming variables and controls in an assembly as per...
11
by: tonicvodka | last post by:
What is the naming convention for functions in c#?
14
by: 42 | last post by:
Hi, Stupid question: I keep bumping into the desire to create classes and properties with the same name and the current favored naming conventions aren't automatically differentiating them......
6
by: dm1608 | last post by:
I'm relatively new to ASP.NET 2.0 and am struggling with trying to find the best naming convention for the BAL and DAL objects within my database. Does anyone have any recommendations or best...
114
by: Jonathan Wood | last post by:
I was just wondering what naming convention most of you use for class variables. Underscore, "m_" prefix, camel case, capitalized, etc? Has one style emerged as the most popular? Thanks for...
35
by: Smithers | last post by:
Is it common practise to begin the name of form classes with "frm" (e.g., frmOneForm, frmAnotherForm). Or is that generally considered an outdated convention? If not "frm" what is a common or...
23
by: Thorsten Kampe | last post by:
Okay, I hear you saying 'not another naming conventions thread'. I've read through Google and the 'naming conventions' threads were rather *spelling conventions* threads. I'm not interested...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.