"Richard Herring" <ju**@[127.0.0.1]> wrote in message
news:Sm**************@baesystems.com...
In message <11*************@corp.supernews.com>, Jon Slaughter
<Jo***********@Hotmail.com> writes
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:R6******************@newsread1.mlpsca01.us. to.verio.net... Jon Slaughter wrote:
[big snip]
> It seems I cannot use templates because I
cannot generate the proper method names are derived from the name of
the
class?
Why do you think that the names have to be different?
Huh? Because I said so? because thats how I will program it.
[...]
class Staff : public Base
{
public:
std::vector<Bar> Bars;
int NumBars() { return (int)Bars.size(); }
And this function?... Name it 'count' and you're on your way to making
your classes generic.
um, but whats the point? if I make it so generic then I loose concreteness
and the simplicity of how it models the application. Why not just call
all
my objects object1, object2, object3, etc...? thats pretty general?
theres
a point when generality makes things worse.
That's not generic, it's merely arbitrary.
Well, I suppose. But I think in the context those are generic names(an
arbitrary name would be more like a random name in my book).
The point of giving a function the same meaningful-but-generic name in all
your classes is that you can then apply a templated algorithm to all of
them without having to worry about which class you're dealing with.
I agree and I tried the generic aproach. while it does simplfy the program a
great deal I still get to a point where I cannot go any farther.
Most of your classes appear to model collections of objects at the next
level of the hierarchy. Abstracting the concept of _collection_ allows you
to do many things with them without bothering about the details of what is
inside the container. In my book that's a big *gain* in simplicity.
I do see your pointer, I was able to do a great deal of simplification by
making it generic and maybe in the long run it is better. Though I'm still
not sure original way is bad as far as using the implementation of the
containers its just bad for managing them(Because one has to manage the
exact same code in several different places when its much easier to manage
just one).
--
Richard Herring
Ok, by using a generic template I run into a huge problem that I don't see
how to fix with my limited knownlege of advanced C++ meta programming. By
fix I mean this: By using a generic template I was able to reduce the
multiplician of my code by a factor of 5 down to 2 but it seems because of
my design I cannot reduce it any farther. The follow code demonstrates the
problem(Note it is not exact and not perfect code I'm only typing enough to
demonstrate the problem and nothing else):
Actually here is the generic template that I just created for my problem
minus all the extraneous code that doesn't relate to the problem directly.
#include <vector>
template <class content>
class RDES
{
private:
std::vector<content *> _content;
public:
RDES(void) { };
RDES(RDES &o)
{
// Make a deep copy of the content
for(int index = 0; index < o.Count(); index++)
{
Add(*(new content(o[index])));
};
}
int Count() { return (int)_content.size(); }
void Add(content &content) { _content.push_back(&content); }
void Remove(int index)
{
delete &(*this)[index];
_content.erase(_content.begin() + index);
}
void Remove() { Remove(Count()-1); }
content& operator[](int index) { return *(_content[index]); }
virtual ~RDES(void)
{
for(int index = 0; index < Count(); index++)
{
Remove();
}
}
} // class RDES
Now, the problem is that I need make a container that is exactly the same as
this container but inherents itself.
i.e.
template <class content>
class RDES : public Properties
.......
But properties is exactly the same class as RDES without inheriting itself.
i.e.
template <class content>
class Properties
.......
where (.... is exactly the same code with RDES replaced by Properties(only
thing removed as the ': public Properties').
ofcourse you can't do this. Why do I need to do it? because the base class
will be a container of properties(the content will be properties for my
model) and the class itself is a container of some other objects(i.e. the
basic will contain properties for those objects).
The issue ofcourse is that the method names from the base class are exactly
the same of the class itself and hence there is no way to distingish from
the bass and the class methods.
So you might say why not just make something like
template <class content>
class RDES
{
private:
std::vector<content *> _content;
std::vector<Property *> _properties;
......
and the thing is that all the code will be duplicated still(so I'm back to
the original problem of having code that is duplicated)
Also Property is itself a RDES class that doesn't inherit Properties.
I could do something like
template <class content>
class RDES
{
private:
std::vector<content *> _content;
public:
RDES Properties;
.....
and then I can access the properties class through an extra field access (so
if I wanted to get to the Add method for the properties I would have to do
someClass.Properties.Add() but I'd prefer someClass.Add() (but ofcourse this
confuses the problem with the child class's Add()... this is the whole
reason why I wanted some type of automatic naming so I Could do
someClass.AddProperties() and someClass.Add() instead of
someClass.Properties.Add()... )
So while using this will solve the problem of the scope it adds and extra
field access I end up getting an infintely nested class because Properties
will contain properties will contain properties and so on.
So what it boils down to I have to have two RDES classes one that inherits
the other(or uses the the extra Properties variable as above)
I.E.
template <class content>
class RDES
{
private:
std::vector<content *> _content;
public:
RDES2<Property> Properties;
RDES(void) { };
RDES(RDES &o)
{
// Make a deep copy of the content
for(int index = 0; index < o.Count(); index++)
{
Add(*(new content(o[index])));
};
}
int Count() { return (int)_content.size(); }
void Add(content &content) { _content.push_back(&content); }
void Remove(int index)
{
delete &(*this)[index];
_content.erase(_content.begin() + index);
}
void Remove() { Remove(Count()-1); }
content& operator[](int index) { return *(_content[index]); }
virtual ~RDES(void)
{
for(int index = 0; index < Count(); index++)
{
Remove();
}
}
} // class RDES
--------------------------------------------
template <class content>
class RDES2
{
private:
std::vector<content *> _content;
public:
RDES2(void) { };
RDES2(RDES &o)
{
// Make a deep copy of the content
for(int index = 0; index < o.Count(); index++)
{
Add(*(new content(o[index])));
};
}
int Count() { return (int)_content.size(); }
void Add(content &content) { _content.push_back(&content); }
void Remove(int index)
{
delete &(*this)[index];
_content.erase(_content.begin() + index);
}
void Remove() { Remove(Count()-1); }
content& operator[](int index) { return *(_content[index]); }
virtual ~RDES2(void)
{
for(int index = 0; index < Count(); index++)
{
Remove();
}
}
} // class RDES2
Notice the only thign different between RDES2 and RDES is "RDES2<Property>
Properties;" Property is a terminal of the recursion(it is a simply a non
RDES class (but it really doesn't matter.. just pointing out that eventually
the recursion ends).
So as you can see I can solve this problem by having two templates but they
are exactly the same except for one minor(well its major) difference. I'm
back were I started because I still have to manage 2 classes(I had to manage
5 before but I can automatic it by writing a small find and replace util
that fixes everything up).
So what I'll probably do is just write program to find and replace what I
need and call it in a bat file to duplicate the files and fix what needs to
be fixed. I've been doing this manually for the last couple of days and was
just seeing if there was a much more general method available. While I do
like the idea of being general I'm not so sure it works out the best in this
situation... though maybe you guys know how to fix the above problem
(basicaly have some conditional template class) then I might go with it.
i.e. if something like this is possible
template <class content>
class RDES
{
private:
std::vector<content *> _content;
public:
#ifdef __RDESProperties
RDES2 Properties;
#endif
.....
then then I do something like
#undef __RDESProperties
typedef RDES<Properties> RDES2
#define __RDESProperties
typedef RDES<Note > Beat; // Note is a terminal of this process
typedef RDES<Beat > Bar;
typedef RDES<Bar > Staff;
typedef RDES<Staff > Score;
Thisway I get my higherarchy with the properties included. Only drawback is
that I have to access my properties as something like Score.Properties but
it isn't that big a deal.
This way I get one generic class that needs to be updated... but problem is
it doesn't work ;/
Any help would be appreciated
Thanks,
Jon
p.s. sorry if I'm being confusing but I'm doing the best I can to explain
the situation.