I need some advice on refactoring templates (this may be advanced or has no solution?)
I have a chunk of working code below, however, the following chunks of code are identical, except one subclasses from on template parameter while the second subclasses from two template parameters.
Lines 24-34
Lines 36-46
I really abhor copy and pasting code - is there any way to refactor these two chunks so the bodies are shared?
ok - I've simplied the structure of the code and essentially ended up with two trees - one pure abstract, and one DeriveMe
the pure abstract tree is useful for Lines 94-95 where we are holding a vector of abstract objects and don't care about the implementation
if anyone notices how this can be simplified any further, please let me know - ty
edit: so now, if I need to add more methods to CommonAbstract, the only other place I will need to edit would be CommonDeriveMe for the implementation
I don't expect the other parts of the interface to change much but if OpenAbstract or CloseAbstract's interface changes, we would have to implement them in the Concrete classes anyway, so that's ok, too
meanwhile, the rest of the code needs no modification
edit: part of the "restrictiveness" of standard C++ seems to be that you need to derive off the same tree to be of the same type or perhaps what you call same class
if you look at languages like Smalltalk or Go, this restriction doesn't exist; in other words, in those languages, as long as you satisfy the same interface, for all intents and purposes, the two objects are equivalent, in the C++ sense that you can store pointers to them in the same STL container like we see on Lines 94-95
in Smalltalk or Go, two objects are of the same type if they implement the interface required of that type - those two objects don't have to have any parent/child relationship with each other
the way I'm doing it isn't great, because I have to maintain a separate abstract tree, but the function calls are the same from the user's POV - the abstraction looks ok beyond Line 94 - perhaps there's a way to refactor this some more to be one tree, but I'm not sure how to do that yet
I was querying whether to now derive CommonDualDeriveMe from CommonDeriveMe< P1 > was ''genuine" beyond the need to save a copy/pasting a few "similar" functions.
well, they're actually identical functions in terms of implementation and interface, and that's why I did that - to minimize headaches should the classes evolve (copy and pasting identical code is evil)
the important requirement is that CommonDualDeriveMe satisfies both the P1 and the P2 interface so that Lines 89, 90 can go into Lines 97, 98 cleanly
of course, I'm open to suggestions if you have a better idea on how I can do this
the problem is the getName() and its implementation with the member string m_name.
in my real classes, there are more like 20 methods and implementations that are shared and should go into some kind of Common class
so my question is, how can I share this code and implementation without adding a lot of copy-and-pasted or boilerplate code?
trying to adhere to "inheritance is not for code reuse", but the alternative seems to be a lot of boilerplate code
here are some possibilities:
1. do it with 2 trees, like what I have now
2. when I started, I attempted to implement this by using 1 tree with MI and got spurious memory errors from valgrind - it would look like what Disch said, adding a CommonImpl class and then delegating this calls to an instance of this class somewhere in the hierarchy (or perhaps just stuffing it in CommonAbstract and deal with the diamond inheritance issues?)
it's late so maybe I'll try 2. tomorrow
edit: yup, much simpler with just one tree - thx Disch - but I have the valgrind issue - lemme see if I can work around that - if not, I hope a valgrind suppression doesn't mask real memory problems