5

I have a container which holds a bunch of pointers to a base class, and a function which takes some input and returns a class which is a subclass of the base class. Which subclass it returns depends on the input.

Right now, I have a giant switch statement like this:

class Base { ... }

class A : public Base { ... }
class B : public Base { ... }
...
class Z : public Base { ... }

Base* depends(int input) {
    switch (input) {
    case 1:
        return new A(...);
    case 2:
        return new B(...);
    ...
    case 26:
        return new Z(...);
    default:
        ...
    }
}

I was wondering if there's any better way to design this. I don't know many "design patterns" (I think that's what they're called) so I don't know if there's a (obvious) better way to design this.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • 1
    It would be great to have a dictionary mapping your keys to classes or class names (or just an array if your keys are ints). But is this possible? See the similar question: http://stackoverflow.com/questions/582331/c-is-there-a-way-to-instantiate-objects-from-a-string-holding-their-class-name – Ray Toal Jul 16 '11 at 05:48
  • @Ray thanks for the link, that question is extremely similar to mine, and pretty much answers teh question. – Seth Carnegie Jul 16 '11 at 07:04

4 Answers4

6

What you are looking for is an Factory Method pattern.

The important thing here is to remove the need for the Base class to have any knowledge of the derived class implementations. It is a bad design for a Base class to have knowledge about Derived classes.

Factory Method pattern addresses the above problem as the creation occurs outside of the Base class.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
1

Its a little hard to work out what you're intending with this, but you might want to consider an Abstract Factory pattern if you want to create a bunch of different subclasses based on some input parameter.

iandotkelly
  • 9,024
  • 8
  • 48
  • 67
1

another way is to create an array where you will put pointers to the functions that will call corresponding constructor. And in your depends() you only will call the function that you need by given input. But any way you need 26 functions in this approach

Fedor Skrynnikov
  • 5,521
  • 4
  • 28
  • 32
1

The integer parameter "input" comes from somewhere. You might be able to let the code that created that int create the actual object instead. That won't work if you are reading the int from disk or something like that.

You might consider setting up a situation where the different subclasses register themselves with the object that creates them. In that case the factory object wouldn't need to know about the subclasses at compile time. You can have this done at start-up time using global variables whose constructors do the registering for each subclass. Your switch statement is simpler and faster, but it does mean you have to keep the switch up to date as you change the subclasses. It's a trade off and I don't think your solution is necessarily inferior to a more elaborate one.

Bjarke H. Roune
  • 3,667
  • 2
  • 22
  • 26
  • Unfortunately that's exactly what this program does - read data from a file. This program needs every bit of efficiency it can get though, so I think sticking with a `switch` will be a good way to go. Thanks. – Seth Carnegie Jul 17 '11 at 23:18
  • @Seth Carnegie One thing you might want to do is have subclasses define a static const field like classId. Then both the code that creates the object and the code that writes out the id to disk can refer to the same field. – Bjarke H. Roune Jul 18 '11 at 01:45
  • yeah, that's what it does. I'd rather do that that RTTI. – Seth Carnegie Jul 18 '11 at 02:20