magnetsharpie
magnetsharpie

Reputation: 13

What's the best way to have a "multitype" member variable in a class?

I'm currently working on adding new functionality to an already defined class in our codebase, and I'm running into issues due to not having encountered a problem like this before (I'm still fairly new to C++/coding). Below is a simplified version of the class:

class Foo {
public:
  Foo();
  ~Foo();

  Input ReturnInput() { return fizz.GetFizzInput(); }
  Output ReturnOutput() { return fizz.GetFizzOutput(); }

private:
  Fizz fizz;
};

I'm trying make it such that the member variable fizz can be of a different type Buzz, and call specific methods (i.e. GetBuzzOutput/Input()) that are only implemented in the Buzz class. Both Fizz and Buzz inherit from the same parent class, but that parent class does not implement these specific methods.

The following are some things I've thought about as options. All of them require adding an argument to Foo's constructor and an additional member variable to let us differentiate which type we want - either Fizz or Buzz.

  1. Add a second member variable of type Buzz and use either member variable as desired. This doesn't seem ideal because every time Foo is constructed, one of these member variables will be unused.

  2. Change the member variable to a pointer to the base class of Fizz and Buzz, and use dynamic_cast to downcast to the appropriate type when calling the specific methods. I don't think this is a great idea either, but I'm less clear on why - it's mostly just a feeling.

  3. Split Foo into two classes, FooFizz and FooBuzz (each of which has either Fizz or Buzz as a member variable), and instantiate the appropriate version depending on which one we want. This seems like the best option, but maybe there's some unseen issue I haven't understood.

Is there a better way to go about this? Am I missing something that would make this much easier? I can't implement virtual methods in the parent class of Fizz and Buzz, unfortunately.

Thanks very much for any advice.

Upvotes: 1

Views: 71

Answers (1)

Jeremy Friesner
Jeremy Friesner

Reputation: 73041

Assuming a given Foo object doesn't need to be able to switch from holding-a-Fizz to holding-a-Buzz at runtime, C++ templates would give you the flexibility you need without the code duplication of writing both a FooFizz and a FooBuzz class:

template <class T> class Foo {
public:
  Foo();
  ~Foo();

  Input ReturnInput() { return t.GetInput(); }
  Output ReturnOutput() { return t.GetOutput(); }

private:
  T t;
};

typedef Foo<Fizz> FooFizz;
typedef Foo<Buzz> FooBuzz;

Upvotes: 1

Related Questions