Reputation: 13
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
.
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.
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.
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
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