Re: Programmer knowledge
From: Gerry Quinn (gerryq_at_indigo.ie)
Date: Wed, 31 Mar 2004 20:45:40 GMT
In article <firstname.lastname@example.org>, "Malcolm" <email@example.com> wrote:
>"Gerry Quinn" <firstname.lastname@example.org> wrote in message
>> Certainly it *ought* to be - but there's no guarantee that it is!
>> Some objects on your array might have a salary() function that
>> returns a string. Even if it returns a numeric type, there's no
>> certainty that it means the same thing. It might be the payment date
>> expressed as an integer.
>All the objects have to be of the same Employee() type, since templates
>don't provide true binding by name.
Well then, that shows why the OO approach is best. An
Employee::Payroll() function can only target classes it ought to be
>> What we want, therefore, is a way of making sure that our array
>> contains objects that have a common meaning for salary() etc. In
>> other words, they should be derived from a base class, which we
>> might call Money (or whatever, that's a bad name but we used it up
>> to now).
>A "Money" class would hold an amount that represents a financial value.
>Probably it would just be a manged integer, but we could derive other
>classes from it, such as "credit", which could be money tagged with an
>Deriving Employee from a money base class, however, on the grounds that
>Employees have a salary attached, is a really bad idea. An Employee "has a"
>salary, but does have an "is a" realtionship with money.
>This of course is the huge problem with OO design - it is very difficult to
>do, and very easy to get into a mess with.
We didn't get into a mess with OO, we gave names to classes with
unidentified roles and meanings to broadly illustrate a point. We
didn't make a design, and treating a usenet thread as a design document
would give poor results irrespective of the programming methodology!
>> But we know (see above) that getting away from it is a bad thing! > We
>gain nothing and lose protection, as well as encapsulation. We
>> only want to use Payroll() with classes where it is meaningful and
>> we know what it means. Using generic programming in this
>> example would be a disastrously bad approach.
>The problem is that C++ doesn't allow us to do what we really want to do,
>which is to run a payroll on any sequence of Employees. In pseudo-C++, what
>we want is
>void payroll(Employee::iterator first, Employee::iterator last)
Your sequence already has iterators - Employee doesn't need them. Just
iterate through your sequence of Employee-derived classes and call
Employee::Payroll() for each instance:
for ( seq::iterator iter = first; iter < last; iter++ )
first and last were selected from a sequence we know to be full of
Employee-derived classes, because we defined it that way:
MySuperSequence< Employee > m_Employees;
>Use of templates allows us to use any type of iterator, which is sensible
>because there is no reason why payroll() should insist on data being in an
>array or any other kind of structure. It also, as a side-effect, allows us
>to pay anything with a name(), NI_number() and salary(). This is very much a
>two-edged sword, because it is very hard to document the function so that
>people can take advantage of this without looking at the source.
A two-edged sword with the handle also filed razor sharp ;-)
>It's also quite common to see C++ programs which make no or very little use
>of inheritance. These programs would be better written in C - you are not
>writing OO programs until objects have relations with each other, which in
>C++ usually means inheritance.
I disagree - inheritance is just one of the way objects relate to each
other. There's no reason why it should be important to any given OO
>Operator functions are something that many programmers dislike, but in fact
>these go well with templates. It is a lot easier to document "must have +
>and - operators defined" than try to specify member functions.
>However a real example of a "special chisel" would be multiple inheritance.
>This could be made to work as a traits (a streetlamp is a light, is a static
>object, is an electricity consumer etc) but the C++ method is really too
>unwieldy to make this manageable.
Once on comp.games.roguelike.development we were discussing the use of
this sort of setup for weapons etc. Two observations came to me
1. This is what MI was designed to do
2. You would be stupid to seriously consider it!
Maybe someone somewhere has used MI for some beneficial process. My
gueses is that whatever it was could have been done either by cloning
interfaces, or (probably more C++ in style) aggregating classes
embodying the interfaces.
[Note: any posts from me will be rare over the next few weeks as I am
- Gerry Quinn