Need help with switch() mess

  • Thread starter Christopher Benson-Manica
  • Start date
C

Christopher Benson-Manica

At the moment, I've got the following situation (not my code):

// Assume appropriate headers have been included

enum MyType { ctypeNone, ctypeA, ctypeB, ctypeC };

class MyBaseClass {
static MyBaseClass* Create( const char * );
static MyType PickAClass( const char * );
};

class TypeA : public MyBaseClass {
typeA( const char * );
};

class TypeB : public MyBaseClass {
typeB( const char * );
};

class TypeC : public MyBaseClass {
typeC( const char * );
};

// actual implementation of Type* constructors omitted

MyType MyBaseClass::pickAClass( const char *str ) {
// do secret voodoo with str
return ctypeA; // or ctypeB, or ctypeC, or ctypeNone
}

MyBaseClass* MyBaseClass::Create( const char *str ) {
switch( PickAClass(str) ) {
case ctypeA: return( new TypeA(str) );
case ctypeB: return( new TypeB(str) );
case ctypeC: return( new TypeC(str) );
default: return NULL;
}
}

(Here there are only 3 types - in the actual code, there are 20.)

Now, this setup works correctly, but it strikes me as being
distinctively suboptimal. I'd like to create an array of function
pointers to the Type* constructors, so I could just index into that
array instead of messing with a 21-case switch statement. I don't
suppose I can take the address of a constructor, right? If so, what
is its type? If not, and if it is in fact worth the effort to revamp
this code, what do you suggest?
 
S

Sharad Kala

Christopher Benson-Manica said:
At the moment, I've got the following situation (not my code):

// Assume appropriate headers have been included

enum MyType { ctypeNone, ctypeA, ctypeB, ctypeC };

class MyBaseClass {
static MyBaseClass* Create( const char * );
static MyType PickAClass( const char * );
};

class TypeA : public MyBaseClass {
typeA( const char * );
};

class TypeB : public MyBaseClass {
typeB( const char * );
};

class TypeC : public MyBaseClass {
typeC( const char * );
};

// actual implementation of Type* constructors omitted

MyType MyBaseClass::pickAClass( const char *str ) {
// do secret voodoo with str
return ctypeA; // or ctypeB, or ctypeC, or ctypeNone
}

MyBaseClass* MyBaseClass::Create( const char *str ) {
switch( PickAClass(str) ) {
case ctypeA: return( new TypeA(str) );
case ctypeB: return( new TypeB(str) );
case ctypeC: return( new TypeC(str) );
default: return NULL;
}
}

(Here there are only 3 types - in the actual code, there are 20.)

Now, this setup works correctly, but it strikes me as being
distinctively suboptimal. I'd like to create an array of function
pointers to the Type* constructors, so I could just index into that
array instead of messing with a 21-case switch statement. I don't
suppose I can take the address of a constructor, right? If so, what
is its type? If not, and if it is in fact worth the effort to revamp
this code, what do you suggest?

Have you looked at the factory pattern?
 
D

David Harmon

I'd like to create an array of function
pointers to the Type* constructors, so I could just index into that
array instead of messing with a 21-case switch statement. I don't
suppose I can take the address of a constructor, right?

You would point not to the constructor, but a static function that returns a pointer to a "new"ly allocated instance.
 
J

Jeremy Cowles

> MyBaseClass*
MyBaseClass::Create( const char *str ) {
Have you looked at the factory pattern?

The code he posted actually is a /crude/ factory.
 
T

Thomas Matthews

Christopher said:
At the moment, I've got the following situation (not my code):

// Assume appropriate headers have been included

enum MyType { ctypeNone, ctypeA, ctypeB, ctypeC };

class MyBaseClass {
static MyBaseClass* Create( const char * );
static MyType PickAClass( const char * );
};

class TypeA : public MyBaseClass {
typeA( const char * );
};

class TypeB : public MyBaseClass {
typeB( const char * );
};

class TypeC : public MyBaseClass {
typeC( const char * );
};

// actual implementation of Type* constructors omitted

MyType MyBaseClass::pickAClass( const char *str ) {
// do secret voodoo with str
return ctypeA; // or ctypeB, or ctypeC, or ctypeNone
}

MyBaseClass* MyBaseClass::Create( const char *str ) {
switch( PickAClass(str) ) {
case ctypeA: return( new TypeA(str) );
case ctypeB: return( new TypeB(str) );
case ctypeC: return( new TypeC(str) );
default: return NULL;
}
}

(Here there are only 3 types - in the actual code, there are 20.)

Now, this setup works correctly, but it strikes me as being
distinctively suboptimal. I'd like to create an array of function
pointers to the Type* constructors, so I could just index into that
array instead of messing with a 21-case switch statement. I don't
suppose I can take the address of a constructor, right? If so, what
is its type? If not, and if it is in fact worth the effort to revamp
this code, what do you suggest?

One method I use is to implement static creation methods
in each class. The method takes an ID parameter and will
return a pointer to a new instance if the ID is for the
class.

class TypeA
: public MyBaseClass
{
public:
static MyBaseClass * create(const char * id_text);
};

MyBaseClass *
TypeA ::
create(const char * id_text)
{
return (strcmp(id_text, "TypeA") == 0)
? new TypeA
: NULL;
}

In another method, called a factory, I call each creation
function. If the creation returns non-NULL, then I break
out of the loop. {If all creation functions return NULL,
then an exception.}


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top