Passing an evaluated variable to new in allocating a derived class

R

Raghu Kodali

Hi All,

I am trying to figure out any way to pass an evaluated variable to new?
Please let me know if it is possible.

Please see the example structure of my code as below

class baseclass
{
private:
int foo;
int bar;
public:
virtual void run_func(void)=0;
};

class derivclass_1:public baseclass
{
private:
int xvz;
public:
void run_func(void) { /* do something interesting */}
};

I have the derived classes like derivclass_1,derivclass_2,derivclass_3
etc till derivclass_30

my present way of calling goes something like this

baseclass *bc;
if(x==1)
bc=new derivclass_1;
if(x==2)
bc=new derivclass_2;
if(x==3)
bc=new derivclass_3;

.....
......

if(x==30)
bc=new derivclass_30;


which is looking very inefficient to me.

I want to do SOMETHING like

bc=new derivclass_x;

which will save me alot of lines of code as well as helping me in
isolating the main code if I want to add derivclass_31 at a later point
of time.

Is it possible to do (somehow)?

Thanks
Raghu
 
A

Alf P. Steinbach

* Raghu Kodali:
my present way of calling goes something like this

baseclass *bc;
if(x==1)
bc=new derivclass_1;
if(x==2)
bc=new derivclass_2;
if(x==3)
bc=new derivclass_3;

....
.....

if(x==30)
bc=new derivclass_30;


which is looking very inefficient to me.

I want to do SOMETHING like

bc=new derivclass_x;

which will save me alot of lines of code as well as helping me in
isolating the main code if I want to add derivclass_31 at a later point
of time.

Is it possible to do (somehow)?

Map id's to factory functions, e.g. an array or std::map or more
elaborate factory repository, depending on your requirements.
 
V

Victor Bazarov

Alf said:
* Raghu Kodali:



Map id's to factory functions, e.g. an array or std::map or more
elaborate factory repository, depending on your requirements.

Initialising that map is going to have pretty much the same number of
lines. But now there will be two places to worry about: the map
initialisation code *and* each class implementation where you need to
add a "factory function". I am not really sure how it's superior to
this, which is essentially a switch statement. If the map is not
an 'std::map' but an array of pointers to functions, it's probably
marginally faster than a switch statement. The added complexity of
the classes is what would kill it for me, though.

V
 
B

Bob Hairgrove

Hi All,

I am trying to figure out any way to pass an evaluated variable to new?
Please let me know if it is possible.

Please see the example structure of my code as below

class baseclass
{
private:
int foo;
int bar;
public:
virtual void run_func(void)=0;
};

class derivclass_1:public baseclass
{
private:
int xvz;
public:
void run_func(void) { /* do something interesting */}
};

I have the derived classes like derivclass_1,derivclass_2,derivclass_3
etc till derivclass_30

my present way of calling goes something like this

baseclass *bc;
if(x==1)
bc=new derivclass_1;
if(x==2)
bc=new derivclass_2;
if(x==3)
bc=new derivclass_3;

....
.....

if(x==30)
bc=new derivclass_30;


which is looking very inefficient to me.

I want to do SOMETHING like

bc=new derivclass_x;

which will save me alot of lines of code as well as helping me in
isolating the main code if I want to add derivclass_31 at a later point
of time.

Is it possible to do (somehow)?

Can x be known at compile time? If so, you can use template classes
which can all derive from the non-template base class. Otherwise,
you're pretty much stuck with the above, or you could wrap your giant
switch statement in some kind of factory function.
 
R

Raghu Kodali

There is no way I am going to know x at compile time. x is basically
derived from one of the command line arguments passed on to the
program.

So, I think I am stuck with my if/switch-case.

Thanks
Raghu
 
A

Alf P. Steinbach

* Raghu Kodali:
There is no way I am going to know x at compile time. x is basically
derived from one of the command line arguments passed on to the
program.

So, I think I am stuck with my if/switch-case.

Did you read my earlier reply?
 
R

Raghu Kodali

Alf said:
* Raghu Kodali:

Did you read my earlier reply?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Hi Alf,

I did read your message. I am not very comfortable with factory
functions & map. I started reading them yesterday after your mail. I
will update you pretty soon wether it works for me or not.

Thanks
Raghu
 
T

TB

Raghu Kodali sade:
Hi Alf,

I did read your message. I am not very comfortable with factory
functions & map. I started reading them yesterday after your mail. I
will update you pretty soon wether it works for me or not.

Thanks
Raghu

Here's one solution if you feel that your current if-statements are
ugly/insufficient/or something.

#include <new>
#include <vector>

class BaseClass {};
class DerivedClass_1 : public BaseClass {};
class DerivedClass_2 : public DerivedClass_1 {};

template<typename T>
class Allocator {
public:
static BaseClass * Alloc() throw (std::bad_alloc) {
return new T;
};
};

std::vector<BaseClass * (*)()> AllocateIndexClass;

#define POPULATE(VECTOR,CLASS) \
VECTOR.push_back(&Allocator<CLASS>::Alloc)

int main(int argc, char* argv[])
{
POPULATE(AllocateIndexClass,BaseClass);
POPULATE(AllocateIndexClass,DerivedClass_1);
POPULATE(AllocateIndexClass,DerivedClass_2);

// allocate a new DerivedClass_2 object
BaseClass * bc = AllocateIndexClass[2]();
delete bc;

return 0;
}

Or if you need more control of the associated index use this
macro with a std::map<unsigned,BaseClass * (*)()> instead:

#define POPULATE(MAP,INDEX,CLASS) \
MAP[INDEX] = &Allocator<CLASS>::Alloc

This way provides more control over what class a certain index
does allocate. You could change it during execution to
adjust it to the situation.

Of course, you could use templates instead of macros.
 

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
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top