Design discussion: inheritance + (template or parameters)

A

arch

Hi,

I am trying to implement a class hierarchy where there will be a base class
defining the interface and some common operations (interface+implentation):
Constraints : no STL. This will be implemented for an ARM processor for an
embedded application.

class ActorA: public Actor;
class ActorB: public Actor;
class ActorC: public Actor;

Actor {
virtual void decide() = 0;
void Preprocess();
virtual void Process() = 0;
}

Decide() and Process() are interfaces defined by this base class.

My problem is with the types associated with these actor objects. Internally
all these classes act on a two dimensional array of values of size (X, Y)
which will be configurable. SizeX and SizeY are in the order of 20-40. Each
element of the array can be a single value, two values, or 7 values. .
Specifically,

ActorA will act on a 2-D array of single values
ActorB will act on a 2-D array of doublets.
ActorC will act on a 2-D array of 7-lets.

The fact that you may have 1, 2, or 7 values only affect the decide()
function. The process() functions acts on each of these values independently
of the decision is made.

Possibilities:
1) Everything is a parameter
Actor::Actor(SizeX, SizeY, N) {
// N : n-tuple
pArray = new int(SizeX*SizeY*N);
// Define access operators
// etc.

Actor will be general enough to do everything.
ActorX will be using the access operators etc. from Actor class and just
implement decide() and process().

2) Define a template
template <int SizeX, int SizeY, int N>
class Actor {
private:
int[SizeX][SizeY][N];
public:
Actor() {}
// etc.

Alll other actor classes will be inherited from this template base class. i
believe this is doable. No need to define access operators in this case.

Those are the two ideas I have. Later there may be a need to define other
Actors defining other decide/process pairs. As you realize, SizeX and Y are
not known at compile time, but N is known. I would be happy to find a way to
make the dependency on N specific to actors. Template based idea seems to do
it, but I am not sure...

Which one is better? Which is a better design? code size is a slightly
lesser issue than speed.

Thanks for the feedback.

Arcin
 
G

Gianni Mariani

arch wrote:
....
The fact that you may have 1, 2, or 7 values only affect the decide()
function. The process() functions acts on each of these values independently
of the decision is made.

Possibilities:
1) Everything is a parameter
Actor::Actor(SizeX, SizeY, N) {
// N : n-tuple
pArray = new int(SizeX*SizeY*N);
// Define access operators
// etc.

Actor will be general enough to do everything.
ActorX will be using the access operators etc. from Actor class and just
implement decide() and process().

2) Define a template
template <int SizeX, int SizeY, int N>
class Actor {
private:
int[SizeX][SizeY][N];
public:
Actor() {}
// etc.

Alll other actor classes will be inherited from this template base class. i
believe this is doable. No need to define access operators in this case.

Those are the two ideas I have. Later there may be a need to define other
Actors defining other decide/process pairs. As you realize, SizeX and Y are
not known at compile time, but N is known.

If SizeX and SizeY are not known at compile time then the preceeding
template won't work for you. Template parameter values MUST BE KNOWN at
compile time.

I would be happy to find a way to
make the dependency on N specific to actors. Template based idea seems to do
it, but I am not sure...

Which one is better? Which is a better design? code size is a slightly
lesser issue than speed.

Another alternative:

template <int N>
class Actor {
private:
typedef int value_type[N];
value_type * m_values;
int m_xsize;
int m_ysize;

public:
Actor(int SizeX, int SizeY)
: values( new value_type[ SizeX * SizeY ] ),
m_xsize( SizeX ),
m_ysize( SizeY )
{
}
};


I really don't have enough to go on to help you but you may get a slight
performance improvement by using the Actor<int> template because there
is a constant multiply and hence the compliler may be able to produce
some multiply optimizations.
 
A

arch

Gianni Mariani said:
arch wrote:
...
The fact that you may have 1, 2, or 7 values only affect the decide()
function. The process() functions acts on each of these values independently
of the decision is made.

Possibilities:
1) Everything is a parameter
Actor::Actor(SizeX, SizeY, N) {
// N : n-tuple
pArray = new int(SizeX*SizeY*N);
// Define access operators
// etc.

Actor will be general enough to do everything.
ActorX will be using the access operators etc. from Actor class and just
implement decide() and process().

2) Define a template
template <int SizeX, int SizeY, int N>
class Actor {
private:
int[SizeX][SizeY][N];
public:
Actor() {}
// etc.

Alll other actor classes will be inherited from this template base class. i
believe this is doable. No need to define access operators in this case.

Those are the two ideas I have. Later there may be a need to define other
Actors defining other decide/process pairs. As you realize, SizeX and Y are
not known at compile time, but N is known.

If SizeX and SizeY are not known at compile time then the preceeding
template won't work for you. Template parameter values MUST BE KNOWN at
compile time.

I thought I would be able to do it. Oh, what you are saying is that if I
have
SizeX = GetInput();
SizeY=GetInput();
I would be happy to find a way to
make the dependency on N specific to actors. Template based idea seems to do
it, but I am not sure...

Which one is better? Which is a better design? code size is a slightly
lesser issue than speed.

Another alternative:

template <int N>
class Actor {
private:
typedef int value_type[N];
value_type * m_values;
int m_xsize;
int m_ysize;

public:
Actor(int SizeX, int SizeY)
: values( new value_type[ SizeX * SizeY ] ),
m_xsize( SizeX ),
m_ysize( SizeY )
{
}
};

I like your alternative in the sense that int[N] typedef makes it look like
an internal type. And since I know the value of N for different actors, that
works great. Since template is out of the picture, that is sth between a
full template (which is not possible) and full 1-D array implementation.

And this fits the objects in my domain a lot closer.

Thank you.

I am wondering: Is it worth defining classes for these different int[N]
datatypes. OR Let's assume that these classes are created for other needs.
In this case the template will turn into

template <typename NewType>
class Actor {
private:
NewType *mp_values;
//etc...
}

Each NewType will include the appropriate int[N] private member where N is
1,2,7, etc.

it is not really look useful to create them unless they are created for
other purposes. To me, even when these NewTypes are created, it may be
simpler (=faster?) to stick to your definition of Actor.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top