Topic: Are there any plans to make "properties" standard?
Author: David R Tribble <david@tribble.com>
Date: 1999/07/01 Raw View
Lisa Lippincott wrote:
> In my experience, properties are an essential abstraction for
> connecting objects within a program to external interfaces. In
> addition to Borland's library, I cite Apple's AppleScript and NeXT's
> Interface Builder as examples of this use.
I haven't been following this thread very closely, but it seems to
me that something resembling "property closures" can be written using
templates (assuming I understand the meaning of "closures" in the
context of this thread):
// Warning: Untested code
template <class T>
class Closure
{
public:
~Closure();
Closure(T & (*read)(T &o),
void (*write)(T &o, const T &r));
T & read() const; // Get the value
void write(const T &r); // Set the value
T & operator =(const T &r);
// Assign the value
operator T() const; // Retrieve the value
private:
T val; // The value
T & (*readf)(T &o); // Value reading func
void (*writef)(T &o, const T &r);
// Value writing func
};
template <class T> inline
T Closure<T>::operator T() const
{
// Read the value
return (*readf)(*this);
}
template <class T> inline
T & Closure<T>::operator =(const T &r)
{
// Write the value
(*writef)(*this, r);
return *this;
}
Now we can declare a class with a member of type 'Closure<float>'
which has a "reader" and "writer" functions associated with it:
class Example
{
public:
Closure<float> color;
private:
float & getColor(float &o);
void setColor(float &o, const float &v);
};
Example::Example():
color(&getColor, &setcolor) // Establish reader/writer
// funcs for .color
{
...
}
(Note that member 'color' contains a float value as well as the
overhead of two function pointers.)
Now we can access the 'color' member of an 'Example' object, which
indirectly invokes the reader and writer functions:
Example ex;
float f;
ex.color = 1.5; // Calls color.operator =(),
// which calls color.setColor()
f = ex.color; // Calls color.operator T(),
// which calls color.getColor()
This would be even better if we could find a way of eliminating the
overhead of the two function pointers (which might be possible if
the reader and writer functions are static member functions).
Or am I on the wrong track here?
-- David R. Tribble, david@tribble.com --
Those who do not study for-loops are destined to repeat them.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Lisa Lippincott <lisa_lippincott@advisories.com>
Date: 1999/07/05 Raw View
David R Tribble <david@tribble.com> wrote:
> I haven't been following this thread very closely, but it seems to
> me that something resembling "property closures" can be written using
> templates (assuming I understand the meaning of "closures" in the
> context of this thread):
[ code snipped ]
> Or am I on the wrong track here?
Apart from a few details you missed in the thread, you are on the right
track.
First, to avoid confusion, the word closure is already being used
on a different (but slightly related) context; I would avoid it here.
Second, properties need to work even when their value must be calculated,
rather than stored. I think that, modulo syntax errors, your code does
handle such properties, but it also has the unused "val" member, so I'm
not sure what your intent was.
Third, as you noted, the size of the property object is a problem; adding
a property can cause unreasonable overhead for some objects. Much of this
thread has been about tricks to cut down that overhead. As I understand
the state of the thread, the in-the-object overhead can be completely
eliminated at the cost of an extra pointer in (smart) property pointers
and property references, plus either a lot of coding trouble or an
extra pair of parentheses.
--Lisa Lippincott
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dave Abrahams <abrahams@mediaone.net>
Date: 1999/06/27 Raw View
In article <210619991710518087%lisa_lippincott@advisories.com> , Lisa
Lippincott <lisa_lippincott@advisories.com> wrote:
> Q: What does a checkbox do?
> A: It exposes a boolean property to the user.
>
> Yes, properties, like getters and setters, expose an aspect of a class.
> But, by defintion, they expose interface. Sometimes a property is
> a good interface, sometimes it isn't. Likewise, a checkbox isn't always
> the best way to control a program.
Okay, points well taken.
Now we get to the heart of the matter.
> In my experience, properties are an essential abstraction for connecting
> objects within a program to external interfaces. In addition to
> Borland's library, I cite Apple's AppleScript and NeXT's Interface
> Builder as examples of this use.
1. How does this abstraction help?
2. Does the presence or absence of the parentheses in the syntax needed to
use the standard language features for the property abstraction have any
bearing?
3. If they're essential, why haven't I ever missed them when connecting
objects within a program to external interfaces?
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: gfm@mira.net (Graham Menhennitt)
Date: 1999/06/25 Raw View
On 23 Jun 1999 01:16:07 -0400, Pete Becker <petebecker@acm.org> wrote:
>Dave Abrahams wrote:
>>
>> Isn't the use of properties a lot like exposing an implementation? Isn't it
>> often the case that even using setter and getter functions is often a sign
>> of insufficient abstraction in the design? Even if you won't accede to the
>> previous statement, does a property really provide any advantage at all over
>> using get/set functions?
>
>Not really. The underlying reason for properties is that they are one
>third of the PME model (Properties, Methods, Events) which is at the
>root of VCL and Borland's Builder products. Properties can be set at
>design time (i.e. when you're laying out your dialog boxes, etc.), so
>they need to be something with a uniform interface that tools can
>interact with. When you're editing an object in Builder you have an
>"Object Inspector" which lists all of the object's properties, and lets
>you change their values from the Inspector. When you run the
>application, the values that you set at design time are the initial
>values.
This is a non-argument. For editing the object at design time, you could
easily use something outside the language. Perhaps a separate file which
describes the object inspector's "properties" and the associated functions
to call when they are read or written. Or how about specially formatted
comments within the class declaration that achieve the same thing as the
current Borland properties. The Builder IDE can read and interpret these
comments for use by the object inspector. The user's source and the VCL
source still have to call the functions as in normal C++.
e.g.
class Point {
public:
int GetX();
int GetY();
void SetX(int);
void SetY(int);
//**__property int X = {read=GetX, write=SetX};
//**__property int Y = {read=GetY, write=SetY};
...
};
Then there is no _need_ to modify the language (as far as properties are
concerned).
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: William Roeder <broeder@titan.com>
Date: 1999/06/25 Raw View
Sigbjoern Revheim wrote:
>
> "Stanley Friesen [Contractor]" wrote:
>
> > I do not think this is required for member objects. The only requirement
> > is that all *complete* objects use at least one byte. This, I think,
> > leaves the compiler free to optimize away all empty data members.
>
> I don't think the compiler can do that. You can take the address of member
> objects, and if they occupied zero byte you could risk that several objects
> had the same address.
<snip example>
std 9.3(draft): A class with an empty sequence of members and base class
objects is an empty class. Complete objects and member subobjects of an
empty class type shall have nonzero size. 91)
91) That is, a base class subobject of an empty class type may have zero
size.
--
__ _ __ Stanley Fujitake (Honolulu) held the dice for 3
/ ) / / ' ) ) hours 6 minutes at the California Hotel and
/--' * / / /--' _ _ /> _ / _ __ Casino before a seven appeared
/__)__/\_/\_/\_ / \_(_) (__(_/\_(/_/ (_ mailto:broeder@titan.com
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1999/06/26 Raw View
Graham Menhennitt wrote:
>
> This is a non-argument. For editing the object at design time, you could
> easily use something outside the language. Perhaps a separate file which
> describes the object inspector's "properties" and the associated functions
> to call when they are read or written. Or how about specially formatted
> comments within the class declaration that achieve the same thing as the
> current Borland properties. The Builder IDE can read and interpret these
> comments for use by the object inspector. The user's source and the VCL
> source still have to call the functions as in normal C++.
Using a separate file leads to maintenance headaches. That's why nobody
wants to use .DEF files in Windows any more -- having to maintain a list
a hundred functions by their mangled names gets old very fast. Specially
formatted comments have the drawback that they are comments. Programmers
shouldn't have to write comments to explain to the compiler what their
code means.
I'm surprised that nobody's mentioned the Java hack: when you see two
methods named getXXX and setXXX, then XXX is a property.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: gbush@my-deja.com
Date: 1999/06/27 Raw View
Property is a natural and complete lexical element, while getter/setter
is just an implementation detail. In reality there may be no setter or
getter and may be other functions associated with an entity that we
call property (Borland also uses default value, store function, etc.)
So you have a system of several functions( or whatever) that always
work together and that constitute a single property which gives you
another layer of abstraction. There are many things in C++ that are
"redundant" but make programming more effective; if we want to reduce
C++ to the minimal necessary set then it will be really pathetic
language.
Gene.
In article <3772a109.95225827@news.mira.net>,
gfm@mira.net (Graham Menhennitt) wrote:
> On 23 Jun 1999 01:16:07 -0400, Pete Becker <petebecker@acm.org> wrote:
>
> >Dave Abrahams wrote:
> This is a non-argument. For editing the object at design time, you
could
> easily use something outside the language. Perhaps a separate file
which
> describes the object inspector's "properties" and the associated
functions
> to call when they are read or written. Or how about specially
formatted
> comments within the class declaration that achieve the same thing as
the
> current Borland properties. The Builder IDE can read and interpret
these
> comments for use by the object inspector. The user's source and the
VCL
> source still have to call the functions as in normal C++.
>
> e.g.
>
> class Point {
> public:
> int GetX();
> int GetY();
> void SetX(int);
> void SetY(int);
> //**__property int X = {read=GetX, write=SetX};
> //**__property int Y = {read=GetY, write=SetY};
> ...
> };
>
> Then there is no _need_ to modify the language (as far as properties
are
> concerned).
>
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Sigbjoern Revheim <Sigbjorn.Revheim@nsd.uib.no.nospam>
Date: 1999/06/23 Raw View
What I have missed in this discussion is array properties. If you need to do
special handling when modifying an element, you can do this with properties but
not by overloading operator [].
Example:
__property double Data[int Index]={read=GetData,write=SetData};
In addition you can have multidimensional arrays:
__property double Data[int Column][int Row]={read=GetData,write=SetData};
Normal properties are possible to simulate with templates, but I don't see any
way to do this with array properties.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: markcshaw@my-deja.com
Date: 1999/06/23 Raw View
> Ok, so my question is: is this being considered by the standardization
> committee?
>
I read through the discussion on this topic and could not find what
problem with the language BCB properties were supposed to solve.
Reading through Plauger's articles in CUJ, it would seem that a
language extension is likely to be added to C++ (when the standards
bodies next open the standard for updating) if experience has shown
that it solves a general problem which cannot be expressed in the
language already. (The addition of the data type: 'bool' is an
example - the desired behaviours cannot be modeled by an enumeration or
a class.)
My question regarding BCB's properties would be: what problems do they
solve that C++ can't handle already? Are there any? Perhaps Borland
would like to say what problem they were solving when they added their
language extension.
Just a thought...
Mark Shaw
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Lisa Lippincott <lisa_lippincott@advisories.com>
Date: 1999/06/24 Raw View
Dave Abrahams <abrahams@mediaone.net> asks:
> Isn't the use of properties a lot like exposing an implementation? Isn't it
> often the case that even using setter and getter functions is often a sign
> of insufficient abstraction in the design? Even if you won't accede to the
> previous statement, does a property really provide any advantage at all over
> using get/set functions?
Q: What does a checkbox do?
A: It exposes a boolean property to the user.
Yes, properties, like getters and setters, expose an aspect of a class.
But, by defintion, they expose interface. Sometimes a property is
a good interface, sometimes it isn't. Likewise, a checkbox isn't always
the best way to control a program.
(Some people have posted about properties which necessarily control a
simple data member. Such properties do expose implementation, and
I don't care for them; I disregard them here.)
In my experience, properties are an essential abstraction for connecting
objects within a program to external interfaces. In addition to
Borland's library, I cite Apple's AppleScript and NeXT's Interface
Builder as examples of this use.
--Lisa Lippincott
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Sigbjoern Revheim <Sigbjorn.Revheim@nsd.uib.no.nospam>
Date: 1999/06/22 Raw View
"Stanley Friesen [Contractor]" wrote:
> I do not think this is required for member objects. The only requirement
> is that all *complete* objects use at least one byte. This, I think,
> leaves the compiler free to optimize away all empty data members.
I don't think the compiler can do that. You can take the address of member
objects, and if they occupied zero byte you could risk that several objects
had the same address.
Just try the following code:
#include <iostream>
class EmptyContainer
{
class Empty{} e1,e2,e3;
};
int main()
{
std::cout<<sizeof(EmptyContainer)<<"\n";
}
The program returns 24 in C++ Builder 4 with quadword alignement. Since it is
normal to use alignment on Windows compilers, this shows that empty objects
cause very much bloating.
I tried the code on a GNU compiler on Solaris, and it returned 3, the same as
C++ Builder would do with byte alignement.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1999/06/23 Raw View
Dave Abrahams wrote:
>
> Isn't the use of properties a lot like exposing an implementation? Isn't it
> often the case that even using setter and getter functions is often a sign
> of insufficient abstraction in the design? Even if you won't accede to the
> previous statement, does a property really provide any advantage at all over
> using get/set functions?
Not really. The underlying reason for properties is that they are one
third of the PME model (Properties, Methods, Events) which is at the
root of VCL and Borland's Builder products. Properties can be set at
design time (i.e. when you're laying out your dialog boxes, etc.), so
they need to be something with a uniform interface that tools can
interact with. When you're editing an object in Builder you have an
"Object Inspector" which lists all of the object's properties, and lets
you change their values from the Inspector. When you run the
application, the values that you set at design time are the initial
values.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: legalize@xmission.com (Phil McRevis)
Date: 1999/06/20 Raw View
Pete Becker <petebecker@acm.org> spake the secret code
<37685325.B791D034@acm.org> thusly:
>[...] writing programs without regard for memory usage fills up that
>memory awfully fast.
Don't forget that the single biggest impact on performance is likely
to be how effective your program is at using the cache, which is
typically quite small. With lots of redundant data dribbling around,
the cache tends to be underutilized.
--
http://www.xmission.com/~legalize Legalize Adulthood!
legalize@xmission.com
``Ain't it funny that they all fire the pistol, <URL: http://
at the wrong end of the race?''--PDBT www.eden.com/~thewho>
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Dave Abrahams" <abrahams@mediaone.net>
Date: 1999/06/21 Raw View
In article <7kgmcm$66i$1@xmission.xmission.com> , legalize@xmission.com
(Phil McRevis) wrote:
> Don't forget that the single biggest impact on performance is likely
> to be how effective your program is at using the cache, which is
> typically quite small. With lots of redundant data dribbling around,
> the cache tends to be underutilized.
All true, but:
<***begin unsubstantiated claims***>
the kinds of (UI) programs people have been talking about implementing with
properties typically don't have the kind of structure that lend themselves
to cache locality. Most of these event-driven programs run on systems where
other processes will drive the program's data structures out of the cache
between events. Furthermore, almost all UIs are speed-bound by the cost of
calling OS services to manage drawing, etc. And finally, in programs of any
complexity, UI interaction could (almost) be arbitrarily slow without
affecting the user experience. That is, people can't detect slowdowns of a
millisecond or so, and a *lot* of backend processing can go on before you
rack up a whole millisecond.
<***end unsubstantiated claims***>
Anyway, what I'm really interested in is this:
Isn't the use of properties a lot like exposing an implementation? Isn't it
often the case that even using setter and getter functions is often a sign
of insufficient abstraction in the design? Even if you won't accede to the
previous statement, does a property really provide any advantage at all over
using get/set functions?
Ultimately, what I'm trying to figure out is this: do properties really
provide a kind of new expressive power, or is this just a case of a vendor
having supplied an extension which provides a new syntax which some people
have gotten comfortable with and are demanding because they can't adjust to
standard C++?
Any language establishes constraints which lead to particular usage idioms.
Isn't there a point at which we ought to say, "you can do that in c++ but
you can't write it that way. *This* is the way you express that in c++:..."?
-Dave
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Edward Diener <eddielee@abraxis.com>
Date: 1999/06/16 Raw View
Pete Becker wrote:
> It's not member functions that make the containing object bigger, it's
> the members themselves. Even if you can figure out a way to use macros
> to get at the containing object's data, a property object that has no
> data still takes up space. Put several hundred of these inside a class
> and you've got several hundred bytes that aren't doing anything useful.
In these days of 64-128MB of real memory and 3 times that value of virtual
memory for an OS, a program that has several hundred or several thousand or even
several hundred thousand bytes ( doubtful that properties will cause this last
amount of overhead in even the biggest of EXEs-DLLs but let's say it anyway )
that aren't doing anything useful does not bother me too much. Aesthetically,
yes, practically, no. Since I like the aesthetics of the "property" concept as a
programming construct, that overrides for me the extra X number of bytes of data
over a similar program without properties.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Rodrigo de Salvo Braz" <Rodrigo_Braz@brown.edu.nospam>
Date: 1999/06/17 Raw View
Crosbie Fitch wrote in message <7k5bou$g6l$1@soap.pipex.net>...
>Well, I had a go at producing a Property template.
>Competition? - anyone?
Yes, thanks :-)
I posted in this same thread another definition for that.
Mine doesn't spend extra space to keep pointers to member functions. The
functions to be called are determined at compile time.
In your implementation operators like *=, += and ++ won't have the write
function called.
Rodrigo
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Rodrigo de Salvo Braz" <Rodrigo_Braz@brown.edu.nospam>
Date: 1999/06/17 Raw View
Crosbie Fitch wrote in message <7k557i$am5$1@soap.pipex.net>...
>Tritely, the solution is: don't use public data members.
>Instead adopt a convention for property methods, e.g.
>
> class X
> { int s;
> public:
> int Size() const { return s; }
> void Size(int n) { s=n; }
> }
>
>or the GetX, SetX, is another popular one.
The problem with that is that you cannot use inplace assignment operators
like ++ or +=, which can be vital for performance. Moreover, the interface
gets nonuniform, which is a problem because the user has to keep thinking
which interface s/he has to use for each property (direct or getter/setter).
This is a pain at best and threat to future generic algorithms at worst.
In order to make the interface really uniform, you would have to make
everything through getter/setters (creating special ones for inplace
operations), even for very simple, built-in-type data members, which are the
absolute majority of properties. This would mean writing lots and lots of
silly functions that do the very same thing. This would also mean *never*
using the real language operators for *any* class property, but having a
complete set of alternative, equivalent setter member functions, which
sounds really nonsense to me.
Rodrigo
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: gbush@my-deja.com
Date: 1999/06/17 Raw View
Especially I like this line in your code:
> // etc. for all other operators
and this is one of the problems with creating properties as objects.
You have to specify tons of operators for each class they are used with.
Gene.
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1999/06/17 Raw View
Edward Diener wrote:
>
> In these days of 64-128MB of real memory and 3 times that value of virtual
> memory for an OS, a program that has several hundred or several thousand or even
> several hundred thousand bytes ( doubtful that properties will cause this last
> amount of overhead in even the biggest of EXEs-DLLs but let's say it anyway )
> that aren't doing anything useful does not bother me too much. Aesthetically,
> yes, practically, no.
Practically, yes. There are many systems that don't have 64-128MB of
real memory and 3 times that value of virtual memory, and even on those
that do, writing programs without regard for memory usage fills up that
memory awfully fast.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stanley@West.Sun.COM (Stanley Friesen [Contractor])
Date: 1999/06/17 Raw View
In article <37641436.36811B16@acm.org>,
Pete Becker <petebecker@acm.org> wrote:
>It's not member functions that make the containing object bigger, it's
>the members themselves. Even if you can figure out a way to use macros
>to get at the containing object's data, a property object that has no
>data still takes up space. ...
I do not think this is required for member objects. The only requirement
is that all *complete* objects use at least one byte. This, I think,
leaves the compiler free to optimize away all empty data members.
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Rodrigo de Salvo Braz" <Rodrigo_Braz@brown.edu.nospam>
Date: 1999/06/18 Raw View
Pete Becker wrote in message <3768E71B.42F4D99F@acm.org>...
>Rodrigo de Salvo Braz wrote:
>> Doesn't the example I posted a few days ago do it?
>My news server has a message you posted on Tuesday, saying that you had
>posted code two days ago. It also has a header for a message you posted
>on Sunday, but it says the message doesn't exist. Go figure.
>
>Rather than ask you to repost, I'll ask you to show how to use your
>solution for a typical case:
>
>class Window
>{
>public:
> property1 color;
> property2 top;
>private:
> int handle;
>};
>
>int main()
>{
>Window w1;
>Window w2;
>w1.color = 3;
>w2.top = 4;
>return 0;
>}
>
>where the effect of 'w1.color = 3' is to call
>::SetWindowColor(w1.handle, 3), and the effect of 'w2.top = 4' is to
>call ::SetWindowColor(w2.handle, 4).
Ok, my solution would be:
#include "property.h"
class Window
{
private:
class ColorProperty : public property<int>
{
public:
ColorProperty () {};
ColorProperty (int d) : property<int>(d) {};
ColorProperty & operator=(int c) {property<int>::operator=(c);
return
*this;}
ColorProperty & operator=(ColorProperty & c) {return *this = (int)
c;}
void post() {::SetWindowColor(handle, data);} // data is the actual
data in property<int>
};
class TopProperty : public property<int>
{
public:
TopProperty () {};
TopProperty (int d) : property<int>(d) {};
TopProperty & operator=(int t) {property<int>::operator=(t); return
*this;}
TopProperty & operator=(TopProperty & t) {return *this = (int) t;}
void post() {::SetWindowTop(handle, data);} // I don't know the
function to set the top of a Window
};
int handle;
public:
ColorProperty color;
TopProperty top;
};
int main()
{
Window w1;
Window w2;
w1.color = 3;
w2.top = 4;
return 0;
}
Please note that I am for properties as a part of the language; I think the
above is writing too much for such a simple thing.
Having to rewrite the non-inherited assignment operators is particularly
painful.
Also note that the properties above
don't use more space than ordinary ints;
accept all int operators doing the right thing (w1.top++ actually moves
the window), even though I didn't have to define them in this file. That
functionality is factored out in the template property<T>.
Here is property.h:
// property.h
// Header file for properties.
// A property is a value of a certain type that executes a member function
pre
// before accessing its value and another member function post after
accessing
// its value.
// Use derived classes from property<T> and overload pre and post with
functions
// that perform calculations, validations or desired colateral effects.
/* Example:
class A
{
public:
class verbose_int : public property<int>
{
public:
verbose_int() {};
verbose_int(int d) : property<int>(d) {};
verbose_int& operator=(int d) {property<int>::operator=(d); return
*this;}
verbose_int& operator=(verbose_int& d) {return *this = (int) d;}
void pre () {cout << "Pre : " << data << endl;}
void post() {cout << "Post: " << data << endl;}
};
verbose_int i, j;
A():i(10) {}
};
int main(int argc, char **argv)
{
A a;
a.i = 20; // runs pre and post for everything.
a.i += 1;
a.i -= 3;
a.i *= 2;
cout << "prefix -- : " << --a.i << endl;
cout << "postfix -- : " << a.i-- << endl;
cout << a.i << endl;
cout << "Going to assign a.i to a.j\n";
a.j = a.i;
cout << "a.j: " << a.j << endl;
getch();
}
*/
template <class T>
class property
{
protected:
T data;
virtual void pre () {};
virtual void post() {};
public:
property () {}
property (const T& d) : data(d) {}
operator T() {pre(); return data;}
property& operator =(const T& op) {pre(); data = op; post(); return
*this;}
property& operator *=(const T& op) {pre(); data *= op; post(); return
*this;}
property& operator /=(const T& op) {pre(); data /= op; post(); return
*this;}
property& operator %=(const T& op) {pre(); data %= op; post(); return
*this;}
property& operator +=(const T& op) {pre(); data += op; post(); return
*this;}
property& operator -=(const T& op) {pre(); data -= op; post(); return
*this;}
property& operator <<=(const T& op) {pre(); data <<= op; post(); return
*this;}
property& operator >>=(const T& op) {pre(); data >>= op; post(); return
*this;}
property& operator &=(const T& op) {pre(); data &= op; post(); return
*this;}
property& operator ^=(const T& op) {pre(); data ^= op; post(); return
*this;}
property& operator |=(const T& op) {pre(); data |= op; post(); return
*this;}
property& operator ++(void) {pre(); ++data; post(); return *this;}
T operator ++(int) {pre(); T result = data; data++; post(); return
result;}
property& operator --(void) {pre(); --data; post(); return *this;}
T operator --(int) {pre(); T result = data; data--; post(); return
result;}
};
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/06/13 Raw View
In article <376278B4.C9EDDB26@acm.org>, petebecker@acm.org says...
[ ... implementing properties as objects ]
> Yup. And if you do this through objects, then the containing class can
> end up with a half-dozen (perhaps, often many more) empty objects as
> members, inflating its size.
This, of course, is (at least theoretically) a problem anytime you
design a class that contains no data. There are two obvious questions
in my mind: 1) is it more common for a "property" class to contain no
data than for other types of classes, and 2) has this become a
practical problem on a large enough number of real programs to warrant
designing the language to cure/prevent the problem.
Though I don't have any large studies to prove it, my guess is that
the answer to 1 is a resounding NO! In fact, I'd guess that exactly
the opposite is true: a property class is more likely to include some
data than the average of classes as a whole.
It seems to me that the answer to number 2 is similar -- in fact,
based on the small amount of empirical evidence I have handy, programs
written using properties using C++ builder are typically larger and
use more memory than similar programs written without properties, and
compiled with other compilers. I'd also note that an empty class has
to have an unique address, but that address will never actually be
referenced. As such, if it's instantiated as part of a class that has
any padding, the addresses of the padding can be assigned to the empty
objects.
In short, I think the memory overhead of using this method is
typically VERY low in actual practice. Though I don't know of a
compiler that implements it, I can see at least one method that could
completely eliminate the overhead in at least some cases.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Edward Diener <eddielee@abraxis.com>
Date: 1999/06/13 Raw View
Jerry Coffin wrote:
> In article <7jprhq$e8r@cocoa.brown.edu>, Rodrigo_Braz@brown.edu.nospam
> says...
> > Hello,
> >
> > Borland C++ Builder has an extension that I find pretty reasonable and
> > essential to good and uniform OOP.
> > You can define a data member as a property, associating read and write
> > member functions to it.
>
> If the committee tries to build properties into the language, they
> have to pick some set of operations that'll be supported. Almost
> regardless of what they do, they'll end up missing operations some
> people want, while including all sorts of things others don't want.
> Ultimately, any possible set of decisions they make will end up being
> wrong the majority of the time.
I believe that the basic operations on a "property", that one can "set" it's value
and that one can "get" it's value, would be sufficient for a simple and effective
implementation of the idea of a "property". I believe that the vast majority of
people considering this concept as an addition to the C++ language would agree
with me. Furthermore since "properties" should be able to be of any type supported
by C++, there is no need for any other complex operation built into the idea of
"property".
I agree with you that the idea of a "property" is a convenience that can be added
to the language to make the notation of getting and setting a value for a
hypothetical data member clearer to the programmer. However, since I believe that
the overhead of adding this notation to the language would be exceedingly small in
terms of compiler implementation and vendor support, I believe it should be done.
It provides a very simple notation for accessing data members and allows the
actual access to be well hidden within the implementation. If someone has used
properties in C++ Builder it is very easy to get used to their notation, which
doesn't differ in any way from directly accessing data members. As a class
designer implementing properties is also exceedingly easy in C++ Builder.
Sometimes a feature should be added to a computer language that makes the notation
of the language easier to use. I believe that "property" is one of those features.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Rodrigo de Salvo Braz" <Rodrigo_Braz@brown.edu.nospam>
Date: 1999/06/13 Raw View
Pete Becker wrote in message <3761AD21.DAEDEBAC@acm.org>...
>Crosbie Fitch wrote:
>> Granted this might not be 100% identical with a language change, but it
>> would be close eh?
>
>No, it's a long ways off. Think about the size of an object that has
>several hundred of these, or perhaps an array of them.
I sat down and wrote it. It can be done, but it is kind of a pain even to
the user programmer, because s/he has to override constructors and
assignment operators that don't add any functionality actually, just keep
things working when you derive a new property. So her/his code is not as
readable.
As for additional size, this actually doesn't happen, Pete, because the
compiler will generate only the necessary member functions (I hope). Well,
ok, if you use a number of them, your code may be bloated.
// property.h
// Header file for properties.
// A property is a value of a certain type that executes a member function
pre
// before accessing its value and another member function post after
accessing
// its value.
// Use derived classes from property<T> and overload pre and post with
functions
// that perform calculations, validations or desired colateral effects.
/* Example:
class A
{
public:
class verbose_int : public property<int>
{
public:
verbose_int() {};
verbose_int(int d) : property<int>(d) {};
verbose_int& operator=(int d) {property<int>::operator=(d); return
*this;}
verbose_int& operator=(verbose_int& d) {return *this = (int) d;}
void pre () {1, cout << "Pre : " << data << endl;}
void post() {2, cout << "Post: " << data << endl;}
};
verbose_int i, j;
A():i(10) {}
};
int main(int argc, char **argv)
{
A a;
a.i = 20; // runs pre and post for everything.
a.i += 1;
a.i -= 3;
a.i *= 2;
cout << "prefix -- : " << --a.i << endl;
cout << "postfix -- : " << a.i-- << endl;
cout << a.i << endl;
cout << "Going to assign a.i to a.j\n";
a.j = a.i;
cout << "a.j: " << a.j << endl;
getch();
}
*/
template <class T>
class property
{
protected:
T data;
virtual void pre () {};
virtual void post() {};
public:
property () {}
property (const T& d) : data(d) {}
operator T() {pre(); return data;}
property& operator =(const T& op) {pre(); data = op; post(); return
*this;}
property& operator *=(const T& op) {pre(); data *= op; post(); return
*this;}
property& operator /=(const T& op) {pre(); data /= op; post(); return
*this;}
property& operator %=(const T& op) {pre(); data %= op; post(); return
*this;}
property& operator +=(const T& op) {pre(); data += op; post(); return
*this;}
property& operator -=(const T& op) {pre(); data -= op; post(); return
*this;}
property& operator <<=(const T& op) {pre(); data <<= op; post(); return
*this;}
property& operator >>=(const T& op) {pre(); data >>= op; post(); return
*this;}
property& operator &=(const T& op) {pre(); data &= op; post(); return
*this;}
property& operator ^=(const T& op) {pre(); data ^= op; post(); return
*this;}
property& operator |=(const T& op) {pre(); data |= op; post(); return
*this;}
property& operator ++(void) {pre(); ++data; post(); return *this;}
T operator ++(int) {pre(); T result = data; data++; post(); return
result;}
property& operator --(void) {pre(); --data; post(); return *this;}
T operator --(int) {pre(); T result = data; data--; post(); return
result;}
};
[ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "G.B." <gb@home.rutgers.edu>
Date: 1999/06/15 Raw View
Jerry Coffin <jcoffin@taeus.com> wrote in message
news:MPG.11cc7b84ce686cd4989b6e@news.mindspring.com...
> This, of course, is (at least theoretically) a problem anytime you
> design a class that contains no data. There are two obvious questions
> in my mind: 1) is it more common for a "property" class to contain no
> data than for other types of classes, and 2) has this become a
> practical problem on a large enough number of real programs to warrant
> designing the language to cure/prevent the problem.
Answer to 1) Yes, Borland uses properties heavily, many of them for
accessing hundreds of Windows API functions; no data.
2) They are very practical. It allowed Borland to create the best RAD tool,
whithout properties and closures it would be a terrible mess.
[snip]
> It seems to me that the answer to number 2 is similar -- in fact,
> based on the small amount of empirical evidence I have handy, programs
> written using properties using C++ builder are typically larger and
> use more memory than similar programs written without properties, and
> compiled with other compilers. I'd also note that an empty class has
[snip]
You need to compare apples to apples. Borland compilers may not create the
fastest and the smallest code, but they were always intellectually superior.
Just think about what they made of Pascal - it's a masterpiece. If you ask
what is more important in the long run: speed or intellect? - The answer is
pretty obvious, the speed of hardware increases twice in every 18 months or
so but intellectually compilers and languages develop very slowly.
Gene.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Crosbie Fitch" <crosbie@dircon.co.uk>
Date: 1999/06/15 Raw View
I don't mean to be inflammatory, but another 'solution' would be to ban
public data members...
Never use 'em meself. :-)
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: ramon@jl1.quim.ucm.es (Ram'on Garc'ia Fern'andez)
Date: 1999/06/15 Raw View
This is a topic that has been covered by lots of threads in this
newsgroup. I would like to come with some new points.
Very often I hear that properties are just a syntatic convenience.
Although sometimes this is true, properties do have some proper uses
where no replacement can give the same functionality.
For example, if you have a large source code base that depends on a
class like:
class A {
// Other data structures, code members, whatever you can imagine.
public:
int height, width;
};
Now your source code must be adapted to distributed object environment,
where instances of class A are actually remote. Lines like
void fn(A& aa)
{
int x = aa.heigth;
}
must be converted to function calls. Properties provide a natural way
to deal with data members of remote objects.
Anyway, properties can be implemented using standard C++, although there
is some significant space overhead. (Please forgive syntax errors and
focus your comments on the real subject. I did not check the code, but
anyway the solution should be something similar).
template <typename T, typename data_type,
data_type (T::*readfn)(), void (T::*writefn)(data_type&) >
class property {
private:
T* _ptr;
public:
property(T* ptr) : _ptr(ptr) {}
operator data_type() { return _ptr->readfn(); }
void operator= (data_type& x) { _ptr->writefn(x); }
};
class A {
public:
int my_read_function();
my_write_function(int&);
property<A, int, &A::my_read_function, &A::my_write_function>
my_property;
A(/* constructor arguments */) : my_property(this) {
// constructor body
}
};
This has some space overhead, since my_property does have a data member.
Anyway, it would be nice if C++ gurus can think of a reasonable standard
extension, that allows you to implement properties with no overhead.
One possible solution would be to allow to use "this" as a template
paramenter inside a class.
Ramon
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1999/06/15 Raw View
Rodrigo de Salvo Braz wrote:
>
> Pete Becker wrote in message <3761AD21.DAEDEBAC@acm.org>...
> >Crosbie Fitch wrote:
> >> Granted this might not be 100% identical with a language change, but it
> >> would be close eh?
> >
> >No, it's a long ways off. Think about the size of an object that has
> >several hundred of these, or perhaps an array of them.
>
> I sat down and wrote it. It can be done, but it is kind of a pain even to
> the user programmer, because s/he has to override constructors and
> assignment operators that don't add any functionality actually, just keep
> things working when you derive a new property. So her/his code is not as
> readable.
You've missed the point. Properties are typically used for things like
this:
class Window
{
public:
void setColor(int color); // property setter
int getColor(); // property getter
private:
WindowHandle handle;
};
void Window::setColor(int color)
{
SetSystemColor(handle, color);
}
int Window::getcolor()
{
return GetSystemColor(handle);
}
These calls must deal with the state of the window, not the state of
some property object contained in a Window object. If you implement
properties as individual objects, the most straightforward way to do
this is for each object to have a pointer to the object that contains
it, in order to get at the window handle so that it can make the OS
call. Put a hundred different property objects into a window object and
you've got a hundred redundant copies of the pointer to the containing
object.
>
> As for additional size, this actually doesn't happen, Pete, because the
> compiler will generate only the necessary member functions (I hope). Well,
> ok, if you use a number of them, your code may be bloated.
It's not member functions that make the containing object bigger, it's
the members themselves. Even if you can figure out a way to use macros
to get at the containing object's data, a property object that has no
data still takes up space. Put several hundred of these inside a class
and you've got several hundred bytes that aren't doing anything useful.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Rodrigo de Salvo Braz <rodrigo@mailserver.cog.brown.edu>
Date: 1999/06/15 Raw View
On Mon, 14 Jun 1999, Dietmar Kuehl wrote:
> Although I can't tell for sure, I guess that Pete is refering to the
> problem that Borland's properties execute functions in the scope of the
> enclosing class without storing additional information with each
> property (probably, even the functions for reading and writing a
> property are determined at compile time). To do the same with a property
> class embedded into another class, you need to store at least a pointer
> to the enclosing class with each property object.
You are right, but a get around this would be deriving a new "property
class" inside the class that owns the property. In this way things can be
determined at compile time. I posted an example two days ago.
best,
Rodrigo
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Dietmar Kuehl <dietmar.kuehl@claas-solutions.de>
Date: 1999/06/15 Raw View
Hi,
In article <7jv0kb$948@cocoa.brown.edu>,
"Rodrigo de Salvo Braz" <Rodrigo_Braz@brown.edu.nospam> wrote:
> Pete Becker wrote in message <3761AD21.DAEDEBAC@acm.org>...
> >No, it's a long ways off. Think about the size of an object that has
> >several hundred of these, or perhaps an array of them.
Although I can't tell for sure, I guess that Pete is refering to the
problem that Borland's properties execute functions in the scope of the
enclosing class without storing additional information with each
property (probably, even the functions for reading and writing a
property are determined at compile time). To do the same with a property
class embedded into another class, you need to store at least a pointer
to the enclosing class with each property object.
> As for additional size, this actually doesn't happen, Pete, because
the
> compiler will generate only the necessary member functions (I hope).
I guess, Pete was speaking about an increase of the object size which
would indeed be substantial: eg. for integral properties, it is likely
to at least double the size of the member because it has to store the
integral value plus a pointer to the enclosing object (unless you play
non-portable tricks with pointer arithmetic at the cost of an increase
in code size...).
--
<mailto:dietmar.kuehl@claas-solutions.de>
homepage: <http://www.informatik.uni-konstanz.de/~kuehl>
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/06/16 Raw View
In article <041a22447030e69CPIMSSMTPU07@email.msn.com>,
gb@home.rutgers.edu says...
> Jerry Coffin <jcoffin@taeus.com> wrote in message
> news:MPG.11cc7b84ce686cd4989b6e@news.mindspring.com...
> > This, of course, is (at least theoretically) a problem anytime you
> > design a class that contains no data. There are two obvious questions
> > in my mind: 1) is it more common for a "property" class to contain no
> > data than for other types of classes, and 2) has this become a
> > practical problem on a large enough number of real programs to warrant
> > designing the language to cure/prevent the problem.
> Answer to 1) Yes, Borland uses properties heavily, many of them for
> accessing hundreds of Windows API functions; no data.
> 2) They are very practical. It allowed Borland to create the best RAD tool,
> whithout properties and closures it would be a terrible mess.
The question was not whether properties are practical. I'd originally
mentioned the possibility of using classes to implement properties,
and Pete Becker mentioned that when the classes contained no data,
this could result in an increase in the size of the classes that
contained the property classes. The question was whether _that_ extra
size had become a real problem in a real design.
> [snip]
> > It seems to me that the answer to number 2 is similar -- in fact,
> > based on the small amount of empirical evidence I have handy, programs
> > written using properties using C++ builder are typically larger and
> > use more memory than similar programs written without properties, and
> > compiled with other compilers. I'd also note that an empty class has
> [snip]
>
> You need to compare apples to apples. Borland compilers may not create the
> fastest and the smallest code, but they were always intellectually superior.
If this statement has a point (or even a meaning) I've missed it.
"superior" would normally imply some sort of comparison, but you don't
seem to specify what you're comparing. Worse, you seem to be
attributing intellect to compilers, which I'm convinced have none.
> Just think about what they made of Pascal - it's a masterpiece.
I thought this was supposed to be a discussion of the C++ standard,
not an advertisement for Inprise. In any case, yes, I've seen what
they've made of Pascal. In a really good mood, I might replace
"masterpiece" with "mess." If I'd had to use it within the last week,
I would NOT be in a good mood, and my opinion would be completely
unrepeatable.
> If you ask
> what is more important in the long run: speed or intellect? - The answer is
> pretty obvious, the speed of hardware increases twice in every 18 months or
> so but intellectually compilers and languages develop very slowly.
The point Pete raised was about size, not speed. For the moment
though, I'll assume you consider them related, which would
(apparently) mean that you're saying Pete's point didn't really mean
much.
On one hand, you seem to say that properties are a good thing, but
OTOH, you seem to say that the points previously raised in their favor
mean little or nothing, and a point I'd previously raised against
their being added to the language proper (that it would take a LONG
time to add them, even at best) means a lot. I have to admit that I'm
left befuddled as to whether you're arguing for or against them.
Ultimately, if properties were to be added on the basis of reducing
object size, I'd like to see a compelling difference in real, complete
programs to justify the change. At the present time, the difference
appears to be smaller than the typical range of differences we see in
code generation between compilers. Assuming that's the case, I think
this particular reason is meaningless; without trying to put words in
your mouth, you _seem_ to believe it's meaningless regardless.
That begs the question of whether there's something else strongly in
favor of properties being added to the language rather than
implemented as classes. The obvious and clean implementation I can
see in C++ uses templates. Given that both Pascal and Borland's
somewhat Pascal-like language lack anything much like templates, they
clearly can't use anything much like this solution. In fact, I'll go
on record as saying that the only clean way I can see for them to do
anything very similar IS with a language extension.
Your point about the speed of language development is a good one
though: given that we can do properties in C++ today using classes,
should we idly sit by and wait for the next decade or so for the
committee to add them to the language? Especially to save a little
space in our objects, which we both seem to agree we don't care much
about now, and are almost certain to care FAR less about then?
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Crosbie Fitch" <crosbie@dircon.co.uk>
Date: 1999/06/16 Raw View
If you extrapolate this, one will end up wanting a language facility to
simulate public data members, i.e. to have a member that largely behaves
like the member object, but also has special methods defined to notify the
container upon certain accesses, e.g.
The member object is about to be:
Read
Written to (incremented, decremented, reflexively operated on)
Dereferenced
Cast
Operated upon
Indirected through
etc.
And then perhaps there's a need to override default behaviour of accesses of
this object. Sounds like a class to me.
At the risk of appearing 'holier than thou' I think the problem is really
that many people still wish to use public data members, but now realise
their limitations, i.e. if they're exposed, the containing class has little
control over them. Tritely, the solution is: don't use public data members.
Instead adopt a convention for property methods, e.g.
class X
{ int s;
public:
int Size() const { return s; }
void Size(int n) { s=n; }
}
or the GetX, SetX, is another popular one.
You could probably develop a template to automatically generate the
appropriate data & functions.
And if you really want a property that behaves like a data member, then
there is potential for a templated solution. "Go on then, write one!" I hear
someone say... hmmn, might just give it a whirl...
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Crosbie Fitch" <crosbie@dircon.co.uk>
Date: 1999/06/16 Raw View
Well, I had a go at producing a Property template. Here's my pitiful attempt
(I can't even get it to compile on MSVC6). Maybe someone else can come up
with something far better? Just thought I'd set the ball rolling - not being
a template expert myself.
I expect the ideal declaration would be something like this:
template <typename Type,class Handler=DefaultHandler<T> >
class Property {...};
class Fred
{ ? FredHandler; // something to specify how read/write is handled (if
at all)
public:
Property<int,FredHandler> number; // Acts as int (largely)
};
Competition? - anyone?
/****** START OF C++ ******/
#include "stdio.h"
template
< class X
, typename T
>
class Property
{ friend class X;
private:
X* x;
typedef T X::* tpXT;
tpXT p;
typedef T (X::* tReader) ();
tReader pmfnOnRead;
typedef void (X::* tWriter) (T);
tWriter pmfnOnWrite;
Property(X* xx,tpXT tt,tReader pmfnR,tWriter
pmfnW):x(xx),p(tt),pmfnOnRead(pmfnR),pmfnOnWrite(pmfnW) { }
public:
operator T() const { return pmfnOnRead?x->pmfnOnRead():x->p; }
Property& operator=(const T& tt) { if (pmfnOnWrite) x->pmfnOnWrite(tt);
else x->p=tt; return *this; }
// etc. for all other operators
};
class Fred
{
private:
int m_n; // Storage of the property
void OnWrite_n(int n); // This function will take care of writing
int OnRead_n() const; // This function will return the value to read
public:
Property<Fred,int> n;
Fred():m_n(5),n(this,&Fred::m_n,OnRead_n,OnWrite_n) { }
};
void Fred::OnWrite_n(int p_n)
{ printf("Writing %d\n",p_n);
m_n=p_n;
}
int Fred::OnRead_n() const
{ printf("Reading %d\n",m_n);
return m_n;
}
int main(int argc, char* argv[])
{ Fred f;
f.n=5;
int g=f.n;
return 0;
}
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Rodrigo de Salvo Braz" <Rodrigo_Braz@brown.edu.nospam>
Date: 1999/06/11 Raw View
Hello,
Borland C++ Builder has an extension that I find pretty reasonable and
essential to good and uniform OOP.
You can define a data member as a property, associating read and write
member functions to it.
So if you have
class foo
{
public:
__property int i (read_function, write_function);
...
// definitions of read_function and write_function somewhere
};
you can write
foo a;
a.i = 10;
and have a function being executed for this writing.
In fact, I think specifying functions to be executed before and after the
access to the data member would be even better (rather than for reading and
writing).
This seems essential because many times we have properties that have to be
validated or cause colateral effects when getting new values.
For example, the width of a window in a GUI (the window should be resized
upon assignments to this property).
Writing a member function to set this variable is a partial solution,
something like set_width(int new_value).
It is partial, however, because then we can not use operators like += or ++,
which may be essential to performance in cases where the property is of a
complex type and in-place operations are necessary (like matrices).
Maybe more important than that is the fact that such a feature would make
access to properties really uniform, making user code robust to changes such
as having to add code to be executed after assignments of new values to
properties.
Ok, so my question is: is this being considered by the standardization
committee?
Thank you,
Rodrigo Braz
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Arnold the Aardvark" <aardvark@foxholly.demon.co.uk>
Date: 1999/06/11 Raw View
I've wondered about this myself. I concluded that properties
are no more than a minor syntactic convenience, and this makes
it unlikely (in my opinion) that the committee will be motivated
to introduce the new keywords, etc. which would be required.
There are also limitations you mentioned, which would appear
inconsistent with other well formed code.
It is not burdensome to call the Get and Set functions implemented
to protect one's data. Properties increase the complexity of a class
declaration, since you must still implement these functions before
associating them with a property name.
Having said that, I do like properties a lot.
Arnold the Aardvark
===========================
http://www.foxholly.demon.co.uk
ICQ# 30592054
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/06/12 Raw View
Rodrigo de Salvo Braz wrote:
....
> Ok, so my question is: is this being considered by the standardization
> committee?
The current standard is closed; only defect reports are appropriate at
this point. Work on the next release of the standard won't start for
several years. In the meantime, the way to pursue desired changes is to
convince some implementor to try it them out as extensions. There are
even open source implementations, so you could try implementing it
yourself. Experience with how a proposed change works in actual practice
makes it a lot easier to get the change approved. As the C9X standard
has shown, even bad ideas of how to do something, that become
sufficiently widely used, stand a decent chance of making it into the
next standard.
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Edward Diener <eddielee@abraxis.com>
Date: 1999/06/12 Raw View
Rodrigo de Salvo Braz wrote:
> Hello,
>
> Borland C++ Builder has an extension that I find pretty reasonable and
> essential to good and uniform OOP.
> You can define a data member as a property, associating read and write
> member functions to it.
>
> So if you have
>
> class foo
> {
> public:
> __property int i (read_function, write_function);
Actually it is:
__property int i (read = read_function, write = write_function);
but you have the right idea. Also either the "read =" and/or "write = "
accessors can be data members instead of functions.
> ...
> // definitions of read_function and write_function somewhere
> };
>
> you can write
>
> foo a;
> a.i = 10;
>
> and have a function being executed for this writing.
>
> In fact, I think specifying functions to be executed before and after the
> access to the data member would be even better (rather than for reading and
> writing).
I disagree and think that Borland has it right. It is often the case that the
designer will want a different access method for reading a property than for
writing a property. I see little value to a function to be executed after access
to the data member.
> Ok, so my question is: is this being considered by the standardization
> committee?
I would also like to see properties considered as an addition to the language
but I suspect this will not be done because Getter and Setter functions can be
called instead.
In C++ Builder, where properties really shine, is in the fact that they can be
set at design time for components and saved to persistent storage and restored
from persistent storage. In this way much of the functionality of components can
automatically "initialized" and set before the object is actually used at
runtime. Another amazing use of properties in C++ Builder is that events are
represented by properties whose type is a "C++ Builder __closure", which is
essentially a pointer to a function of a given prototype for any class. This
allows event properties to be set to actual member functions which "catch"
events.
Although Getter and Setter functions can be used instead of properties, the
concept of a property as a data member to which Getter and Setter functions can
be attached is a unique enough idea and offers an already easy to use model of
implementation, as in C++ Builder, that I think it should be considered.
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1999/06/12 Raw View
Edward Diener wrote:
>
> I disagree and think that Borland has it right. It is often the case that the
> designer will want a different access method for reading a property than for
> writing a property. I see little value to a function to be executed after access
> to the data member.
>
A clarification: there doesn't have to be a data member. A property is
an abstraction that can be represented by a read function and a write
function. What those functions do is up to the implementor. The read
function can ask the OS what the current window color is, or it can look
it up in a database, or it can return a value stored in a data member.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/06/12 Raw View
In article <7jprhq$e8r@cocoa.brown.edu>, Rodrigo_Braz@brown.edu.nospam
says...
> Hello,
>
> Borland C++ Builder has an extension that I find pretty reasonable and
> essential to good and uniform OOP.
> You can define a data member as a property, associating read and write
> member functions to it.
A couple of years ago Andrew Koenig wrote a column about "anti-
patterns" -- things that look like good ideas, but end up contributing
to the problem instead of the solution. IMO, properties are one of
the best examples of anti-patterns.
> This seems essential because many times we have properties that have to be
> validated or cause colateral effects when getting new values.
> For example, the width of a window in a GUI (the window should be resized
> upon assignments to this property).
>
> Writing a member function to set this variable is a partial solution,
> something like set_width(int new_value).
> It is partial, however, because then we can not use operators like += or ++,
> which may be essential to performance in cases where the property is of a
> complex type and in-place operations are necessary (like matrices).
If you really have something that needs to implement all manner of
assignment operators, you can do that quite easily by making the
"property" an object itself, and overload the operators you need for
that type. As I said above, properties are an anti-pattern -- instead
of breaking the problem down into manageable chunks, you end up with
single classes that try to implement a large number of fundamentally
separate things. You can easily end up with a half-dozen (or more)
different properties, leading to a dozen different member functions,
dealing with a half-dozen fundamentally different sorts of things.
> Maybe more important than that is the fact that such a feature would make
> access to properties really uniform, making user code robust to changes such
> as having to add code to be executed after assignments of new values to
> properties.
If you really want a nice, uniform set of operations for properties,
consider using a template that provides the operations you want, and
is templated on the underlying type of the property. The best thing
here is that the committee doesn't have to try to read your mind about
what sorts of operations you'll want to carry out on your properties.
If the committee tries to build properties into the language, they
have to pick some set of operations that'll be supported. Almost
regardless of what they do, they'll end up missing operations some
people want, while including all sorts of things others don't want.
Ultimately, any possible set of decisions they make will end up being
wrong the majority of the time.
My advice is to get rid of the concept of building everything into a
single class -- breaking a problem up into more classes, even if some
of them border on absolutely trivial, rarely seems to cause a problem.
Just about every time this question comes up, people end up with
hypothetical questions like "what happens when you just end up with
hundreds of classes and get lost in them, even though each one is
simple." I, at least, have never seen this problem arise in practice.
> Ok, so my question is: is this being considered by the standardization
> committee?
Right now, I think it's safe to say that the committee is not actively
considering any new additions to the language -- new additions won't
be allowed until about four years from now. For the first five years
after a standard is passed, the committee can fix things like places
that the standard contradicts itself, but cannot make new additions at
all. In a few cases, there can be a question about whether something
is a new addition, but it seems pretty clear to me that this is almost
purely new additions.
When the committee can make new additions to the language, I believe
(and hope) that this won't be given much consideration anyway. It's
been proposed in a different forms a number of times, which would
normally indicate that it's something worth considering. In this
case, the proposals differ enough that I think almost any set of
features the committee decided on would be wrong the majority of the
time.
I would consider it worthwhile for the committee to consider adding a
property class to the library, with virtual functions for a number of
the most obvious operations. Many of these would do little more than
relate the member functions together so, for example, you would get
both operator- and operator-= by implementing only one function -- the
class itself would associate the two together. In cases where this
would cause efficiency problems, you could override things and
implement the two separately.
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1999/06/12 Raw View
Jerry Coffin wrote:
>
>
> If you really have something that needs to implement all manner of
> assignment operators, you can do that quite easily by making the
> "property" an object itself, and overload the operators you need for
> that type. As I said above, properties are an anti-pattern -- instead
> of breaking the problem down into manageable chunks, you end up with
> single classes that try to implement a large number of fundamentally
> separate things. You can easily end up with a half-dozen (or more)
> different properties, leading to a dozen different member functions,
> dealing with a half-dozen fundamentally different sorts of things.
Yup. And if you do this through objects, then the containing class can
end up with a half-dozen (perhaps, often many more) empty objects as
members, inflating its size.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
---
[ 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 ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]