Refactoring tightly coupled classes when only one side can be changed - c++

Please accept my apologies in advance for the somewhat long-winded question. This is the minimal self-contained example I could come up with... I'm pretty sure there must be some obvious/nice/neat solution to this problem, but I'm currently not able to see it.
Ok, here's the problem: Imagine the following situation (nb. a compileable version of the code is available at http://goo.gl/dhRNex). Suppose
struct Thing1 {
public:
void bar(class Implementation1 &i) {
i.baz();
}
// ...various other methods like bar()
};
struct Thing2 {
public:
void bar(class Implementation2 &i) {
i.qux();
}
// ...various other methods like bar()
};
are given. Unfortunately, these classes are fixed, i.e., can not be changed/refactored.
However, Implementation1 and Implementation2 are changeable. These two classes share a lot of similar code, so it seems natural to put the shared code in a common base class. However, the code is dependent the type of Thing used, but there is no common base class for Thing1 and Thing2, so it seems also natural to use templates. Thus, I came up with the following solution for the base class
template<class T, class S>
struct ImplementationBase {
public:
S *self;
void foo() {
T thing;
thing.bar(*self);
}
// ...lots more shared code like foo()
};
and concrete implementations
struct Implementation1 : public ImplementationBase<class Thing1, class Implementation1> {
public:
Implementation1() {
self = this;
}
void baz() {
std::cout << "Qux!" << std::endl;
}
};
struct Implementation2 : public ImplementationBase<class Thing2, class Implementation2> {
public:
Implementation2() {
self = this;
}
void qux() {
std::cout << "Qux!" << std::endl;
}
};
Ideally, one would use this instead of self in foo, but the problem is that this is of type ImplementationBase<class Thing1, class Implementation1>, but Implementation1 is required. Obviously, the whole thing is quite a mess and the Implementation and Thing classes are too tightly coupled, but I cannot see an easy way out without being able to refactor the Thing classes. So, finally, my questions are:
Is there a better alternative to using the self trick above?
Is there a design that would solve this problem in a better manner? (I have a feeling, there is, but that I'm missing something obvious)
If you have made it this far, thanks a lot for taking the time and reading the whole story and my apologies again for this long-winded question.

You're already using CRTP so you don't need the self at all:
template<class T, class S>
struct ImplementationBase {
public:
S* getThis() { return static_cast<S*>(this); }
void foo() {
T thing;
thing.bar(*getThis());
}
// ...lots more shared code like foo()
};

Related

Optional class members without runtime overhead

I have the following very general problem that I have not found a satisfying solution to yet:
So I want to have two classes A and AData that are basically identical except that the latter has an additional attribute data and each of the classes supports a function foo(), which is different because it depends on the existence of the additional data.
The stupid solution is to copy the entire class and change it slightly, but that leads to code duplication and is hard to maintain. Using std::optional or a pointer lead to additional checks and therefore runtime overhead, right?
My question is whether there is a way to get the same runtime performance as just copying the code without actual code duplication? My current solution is to make AData a derived class and declare it as friend of A and then override the virtual function foo(), but I do not like this approach due to the use of friend.
You can use static polymorphism and curiosly recurring template pattern.
Both A and AData provide foo() but behaviour is class-specfic through doFoo(). Also not using virtual dispatch avoids runtime overhead of vtable lookup.
template <typename TData>
class Abase
{
public:
void foo()
{
static_cast<TData*>(this)->doFoo();
}
};
class A : public Abase<A>
{
friend ABase<A>;
void doFoo() { cout << "A::foo()\n"; }
};
class AData : public Abase<AData>
{
friend Abase<AData>;
int someDataMember;
void doFoo() { cout << "AData::foo()\n"; /*... use someDataMember ... */}
};
Live
Why not use composition:
class A
{
public:
void foo() { /*...*/ }
};
class AData
{
A a;
int someDataMember;
public:
void foo() { /*... use someDataMember ...*/ }
};

Calling templated function of a nested class of derived class out of a nested class of a base class

I wasn't sure about a proper title. It does seem confusing. Sorry for that.
I am not a programmer. So please, bear with me. I am surely using some terminology wrongly.
Here's what I want to achieve:
Have a base class A_base with some nested class (sub-class?) defined in it (B_base). A_base will have all kinds of common functions that do not require specialization. The nested class is providing some interface for communication with another application (there are callbacks in it, which I define according to my needs).
class A_base
{
public:
void a_function()
{
std::cout << "This is a base a_function\n" ;
}
void a_b_function();
class B_base
{
public:
void b_function()
{
std::cout << "This is a base b_function\n" ;
}
void b_a_function();
virtual void b_c_function1(){return;};
virtual void b_c_function2(){return;};
B_base(const std::string& name_in, A_base* ptr_A_in):
name(name_in), ptr_A(ptr_A_in)
{}
protected:
const std::string name;
A_base* ptr_A;
};
B_base* b_object;
A_base(const std::string& name_in):
b_object(new B_base(name_in, this)), name(name_in)
{}
protected:
const std::string name;
};
void A_base::a_b_function()
{
b_object->b_function();
}
void A_base::B_base::b_a_function()
{
ptr_A->a_function();
}
Derive a templated class out of A_base (A_derived) with some additional specialized functionality and another nested class in it (C_class, which is also templated). I chose this to optimize the latency of my program. It doesn't have to be always lightning fast, but there's one particular path in the logic that must be as fast as possible. Therefore, I am trying to eliminate unnecessary branching by using templates.
enum Side{BB=0,SS=1};
template<bool B>
class A_derived : public A_base
{
public:
void a_function()
{
std::cout << "This is a derived a_function\n" ;
}
template<Side S>
class C_class
{
public:
void c_function();
C_class(const std::string& name_in, A_derived* ptr_A_in):
name(name_in), ptr_A(ptr_A_in)
{}
protected:
const std::string name;
A_derived* ptr_A;
};
C_class<Side::BB> c_object_bb;
C_class<Side::SS> c_object_ss;
A_derived(const std::string& name_in):
A_base(name_in), c_object_bb(name_in, this), c_object_ss(name_in, this)
{}
};
Here I am defining the specialized functions (the ones that are supposed to be fast):
template<> template<>
void A_derived<false>::C_class<Side::BB>::c_function()
{
std::cout << "This is a false-BB c_function\n" ;
}
template<> template<>
void A_derived<false>::C_class<Side::SS>::c_function()
{
std::cout << "This is a false-SS c_function\n" ;
}
template<> template<>
void A_derived<true>::C_class<Side::BB>::c_function()
{
std::cout << "This is a true-BB c_function\n" ;
}
template<> template<>
void A_derived<true>::C_class<Side::SS>::c_function()
{
std::cout << "This is a true-SS c_function\n" ;
}
And on top of that there's a need to be able to call some of the specialized functions out of a method of a nested class B_base. The specialized functions belong to a C_class. Hence, B_base knows nothing about it. But I am trying to circumvent this by casting the A_base pointer into A_derived pointer. I know for sure what kind of A_derived will be used in each case.
The problem is, the C_class function has to be called depending on the version of A_derived that is used. But B_base itself is not a templated class. So, clearly the following is not working the way I want it to work:
void A_derived<false>::B_base::b_c_function1()
{
static_cast<A_derived<false>*>(ptr_A)->c_object_bb.c_function();
}
void A_derived<false>::B_base::b_c_function2()
{
static_cast<A_derived<false>*>(ptr_A)->c_object_ss.c_function();
}
void A_derived<true>::B_base::b_c_function1()
{
static_cast<A_derived<true>*>(ptr_A)->c_object_bb.c_function();
}
void A_derived<true>::B_base::b_c_function2()
{
static_cast<A_derived<true>*>(ptr_A)->c_object_ss.c_function();
}
It just complains about redefining functions. And if I add template<> syntaxis it complains that there is not template out there. And it's kinda true. Can't blame the compiler for this.
Can you please suggest me a reasonable solution? How can I call a templated function of a nested class of a derived class from a method of a nested class of a base class?
Thank you.
Added: So, one person suggested in the comments I should use virtual functions instead. After some thinking I decided to clarify. B_base has its functions as virtual, actually. And this is not my code. I just have to deal with it. The reason virtual functions are of little help is that I cannot simply derive my A_base off B_base (due to some reasons). And for the most of B_base's functions I am fine with some common definitions. However, there are 10% of B_base's functions that I want to be specialized, depending on A_derived that is being instantiated.
My back up solution is to not use B_base at all but rather have some derived B_derived that'd be fully defined inside my A_derived. Unfortunately that would mean writing an infinite amount of useless code. Because most of B_base functions do not depend on type of A_derived.

C++ Polymorphism + template member function for selecting return type. How to do it?

I want to implement a class hierarchy for object dispatching. Different classes dispatch different elements, and each class can dispatch its element represented as different data types.
It is better understood through a (faulty) example. This is what I would like to have if virtual function templating was allowed:
class Dispatcher {
template <class ReturnType>
virtual ReturnType getStuffAs();
};
So that I can implement subclasses as:
class CakeDispatcher : public Dispatcher {
template <>
virtual Recipe getStuffAs(){ ... }
template <>
virtual Baked getStuffAs(){ ... }
};
class DonutDispatcher : public Dispatcher {
template <>
virtual Frozen getStuffAs(){ ... }
template <>
virtual Baked getStuffAs(){ ... }
}
So that I can do the following later on:
void function( Dispatcher * disp ) {
// Works for Donut and Cake, but result will be a different Baked object
Baked b = disp->getStuffAs<Baked>();
// works if disp points to a DonutDispatcher
// fails if it is a CakeDispatcher
// can be compiling/linking time error or runtime error. I don't care
Frozen f = disp->getStuffAs<Frozen>();
}
Requirements/constraints:
All possible return types are not known beforehand. That's why I "need" templates.
Each class can provide just some return types.
Classes must have a common ancestor, so that I can store objects through a pointer to parent class and invoke functions through this pointer.
EDIT: I CAN'T use C++11 features, but I CAN use boost library.
Things I've thought about, but are not a solution:
Obviously, virtual template functions
Curiously Recurring Template Pattern: breaks the condition of common ancestor
Using some kind of traits class containing the functionality of children classes, but it does not work because a non-virtual implementation in the parent class does not have access to this information
I could maybe store some typeid info in the parent class, passed by children on construction. This makes possible for the non-virtual parent dispatching method to dynamic-cast itself to the children type... but it appears to be ugly as hell, and I don't know if this can cause some kind cycle-referencing problem.
class Dispatcher {
private:
typeid(?) childType;
public:
Dispatcher(typeid childT) : childType(childT) {}
// NOT VIRTUAL
template <class ReturnType>
ReturnType getStuffAs()
{
// or something equivalent to this cast, which I doubt is a correct expression
return dynamic_cast<childType *>(this)->childGetStuffAs<ReturnType>();
}
};
Then child classes would implement childGetStuffAs functions, which are not virtual too.
I've read like 5-10 related questions, but none of the provided solutions seems to fit this problem.
Can any of you come up with a better solution?
Is there a standard pattern/technique for solving this problem?
EDIT: The real problem
In the real problem, I have physical models with properties that can be represented in multiple ways: functions, matrices, probability distributions, polynomials, and some others (for example, a non-linear system can be represented as a function but not as a a matrix, while a linear system can be transformed to both).
There are also algorithms which can use those models indistinctly, but they could require specific representations for some model features. That's the reason for the "getStuffAs" function. The whole think is a bit complicated --too much to explain it here properly--, but I can guarantee that in this context the interface is well defined: input, computation and output.
My intention was to make this possible assuming that the number of possible representations is fully defined beforehand, and making it possible to transform the products to already existing types/classes that cannot be modified.
However, i'm starting to realize that this is, indeed, not possible in a simple way --I don't want to write a library just for this problem.
#include <cstdio>
// as a type identifier
struct stuff {
virtual void foo() {}
};
template <typename T>
struct stuff_inh : stuff {
};
struct Dispatcher {
template <typename T>
T* getStuffAs() {
return (T*)((getStuffAsImpl( new stuff_inh<T>() )));
}
virtual void* getStuffAsImpl(void*) = 0;
virtual void type() {printf("type::dispatcher\n");}
};
struct Cake : public Dispatcher {
void* getStuffAsImpl(void* p) {
stuff* s = static_cast<stuff*>(p);
printf("cake impl\n");
if (dynamic_cast<stuff_inh<Cake>*>(s) == NULL) {
throw "bad cast";
}
return (void*)(new Cake());
}
virtual void type() {printf("type::Cake\n");}
};
struct Rabbit : public Dispatcher {
void* getStuffAsImpl(void* p) {
stuff* s = static_cast<stuff*>(p);
printf("rabbit impl\n");
if (dynamic_cast<stuff_inh<Rabbit>*>(s) != NULL) {
return (void*)(new Rabbit());
}
else if (dynamic_cast<stuff_inh<Cake>*>(s) != NULL) {
return (void*)(new Cake());
}
else {
throw "bad cast";
}
}
virtual void type() {printf("type::Rabbit\n");}
};
void foo(Dispatcher* d) {
d->getStuffAs<Cake>()->type();
d->getStuffAs<Rabbit>()->type();
}
int main() {
Rabbit* r = new Rabbit;
foo(r);
Cake* c = new Cake;
foo(c);
}
I an not sure about the correctness of this ugly solution, may it be helpful for you. >_<
deletion of resource is not coded for a clearer look.
My solution is a combination of recurring template and diamond inheritance.
At least it's working. :)
#include <iostream>
class Dispatcher
{
public:
template<class T>
T getStuff()
{
return T();
}
};
template<class T>
class Stuffer : public Dispatcher
{
public:
template<class TT=T>
TT getStuff(){
return reinterpret_cast<TT>(this);
}
};
class Cake{
public:
Cake(){}
void print()
{
std::cout << "Cake" << std::endl;
}
};
class Recipe
{
public:
Recipe(){}
void print()
{
std::cout << "Recipe" << std::endl;
}
};
class CakeRecipe : public Stuffer<Cake>, public Stuffer< Recipe >
{
public:
};
int main()
{
Dispatcher* cr = reinterpret_cast<Dispatcher*>(new CakeRecipe());
cr->getStuff<Cake>().print();
cr->getStuff<Recipe>().print();
getchar();
return 1;
}

Interfaces in C++, WITHOUT multiple inheritance

I suspect that the answer to this is "no" or "you're doing it wrong," but:
Is it possible to implement interface-type behavior WITHOUT using inheritance in C++ (11, if it matters)?
I have a couple of different structs,
struct Foo
{
float A;
void Bind()
{ .... }
};
struct Bar
{
float B;
void Bind()
{
}
};
... and others
These are operated on by a method that passes arrays of these structs to another process, and they have to be pretty tightly packed. If I use inheritance, creating a base class that implements the ::Bind() method, then the descendent classes have not only their data, but a VMT, which consumes a significant chunk of a very scarce resource. Other methods need to operate on these different types, but don't really care about the data members or the specifics of the ::Bind() method, which differs greatly between types.
In C# (or, I suspect, java), I'd do something like:
interface ICommon
{
void Bind();
}
struct Foo : ICommon
{
void Bind() { .... };
};
struct Bar : ICommon
{
void Bind() { ..... }
}
I could use a template:
template<typename T>
void Bind(T &item)
{
item.Bind();
}
but this introduces some constraint (ie, template needs to be declared in a header rather than a cpp, etc.) that are less than ideal. I'm aware of some hacks that let you put a template method implementation in the cpp file, but they're kind of messy and I'd rather avoid it.
This may be a "have your cake and eat it, too" request.
(Note that this isn't really a duplicate of other C++ Interfaces questions as I'm trying to avoid the oft-recommended solution of using multiple inheritance.)
You can achieve almost the same result using template parameters:
template <typename TRAIT>
class ICommon
{
TRAIT t;
public: void Bind()
{
t.Bind();
}
}
class FooTrait
{
public: void Bind() { .... };
};
class BarTrait
{
public void Bind() { ..... }
}
typedef ICommon<FooTrait> Foo;
typedef ICommon<BarTrait> Bar;
template <typename T>
void call_bind(ICommon<T> x)
{
x.Bind();
}
int main()
{
Foo f; Bar b;
call_bind(f);
call_bind(b);
}
Is it possible to implement interface-type behavior WITHOUT using inheritance in C++ (11, if it matters)?
Yes. Encapsulation is a viable alternative to inheritance.
You use the interfaces to define some behavior, then return the interface (the interface is still inherited, but not by your main class).
Example:
class IBinder {
virtual void Bind() = 0;
};
class Foo: public WhateverBaseClass {
struct Binder: public IBinder { virtual void Bind() override {} };
Binder b;
public:
IBinder& getBinder() { return b; }
};
Client code:
Foo f;
f.getBinder().Bind();
If you really don't want to use templates or inheritance, you could use overloaded free functions:
void Bind(Foo& foo) {}
void Bind(Bar& bar) {}
int main() {
Foo foo;
Bar bar;
Bind(foo);
Bind(bar);
}
Of course, any function that needs to operate on either type must be either overloaded or templated.
Java's interfaces are just a watered down way of doing evil, evil, cross my heart, we won't ever do that, multiple inheritance. Nothing more.
For your problem, if you want to get a bunch of objects that share an "interface," do as is natural: They belong to the interface's class, i.e., are derived from it. Can create an array of (pointers to) such objects, with a little care even of the objects themselves (but I wouldn't go there unless absolutely necessary, the danger of slicing off something is just too great).
Re: "templates only in headers": Says who? Headers are just included (probably in several different source files), in order to avoid writing the same declarations (and inline definitions) over and over. If you need templates, or classes, or whathaveyou just in a single source file, noboby will force you to create a header just for that.

Enforcing correct parameter types in derived virtual function

I'm finding it difficult to describe this problem very concisely, so I've attached the code for a demonstration program.
The general idea is that we want a set of Derived classes that are forced to implement some abstract Foo() function from a Base class. Each of the derived Foo() calls must accept a different parameter as input, but all of the parameters should also be derived from a BaseInput class.
We see two possible solutions so far, neither we're very happy with:
Remove the Foo() function from the base class and reimplement it with the correct input types in each Derived class. This, however, removes the enforcement that it be implemented in the same manner in each derived class.
Do some kind of dynamic cast inside the receiving function to verify that the type received is correct. However, this does not prevent the programmer from making an error and passing the incorrect input data type. We would like the type to be passed to the Foo() function to be compile-time correct.
Is there some sort of pattern that could enforce this kind of behaviour? Is this whole idea breaking some sort of fundamental idea underlying OOP? We'd really like to hear your input on possible solutions outside of what we've come up with.
Thanks so much!
#include <iostream>
// these inputs will be sent to our Foo function below
class BaseInput {};
class Derived1Input : public BaseInput { public: int d1Custom; };
class Derived2Input : public BaseInput { public: float d2Custom; };
class Base
{
public:
virtual void Foo(BaseInput& i) = 0;
};
class Derived1 : public Base
{
public:
// we don't know what type the input is -- do we have to try to cast to what we want
// and see if it works?
virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }
// prefer something like this, but then it's not overriding the Base implementation
//virtual void Foo(Derived1Input& i) { std::cout << "Derived1 did something with Derived1Input..." << std::endl; }
};
class Derived2 : public Base
{
public:
// we don't know what type the input is -- do we have to try to cast to what we want
// and see if it works?
virtual void Foo(BaseInput& i) { std::cout << "I don't want to cast this..." << std::endl; }
// prefer something like this, but then it's not overriding the Base implementation
//virtual void Foo(Derived2Input& i) { std::cout << "Derived2 did something with Derived2Input..." << std::endl; }
};
int main()
{
Derived1 d1; Derived1Input d1i;
Derived2 d2; Derived2Input d2i;
// set up some dummy data
d1i.d1Custom = 1;
d2i.d2Custom = 1.f;
d1.Foo(d2i); // this compiles, but is a mistake! how can we avoid this?
// Derived1::Foo() should only accept Derived1Input, but then
// we can't declare Foo() in the Base class.
return 0;
}
Since your Derived class is-a Base class, it should never tighten the base contract preconditions: if it has to behave like a Base, it should accept BaseInput allright. This is known as the Liskov Substitution Principle.
Although you can do runtime checking of your argument, you can never achieve a fully type-safe way of doing this: your compiler may be able to match the DerivedInput when it sees a Derived object (static type), but it can not know what subtype is going to be behind a Base object...
The requirements
DerivedX should take a DerivedXInput
DerivedX::Foo should be interface-equal to DerivedY::Foo
contradict: either the Foo methods are implemented in terms of the BaseInput, and thus have identical interfaces in all derived classes, or the DerivedXInput types differ, and they cannot have the same interface.
That's, in my opinion, the problem.
This problem occured to me, too, when writing tightly coupled classes that are handled in a type-unaware framework:
class Fruit {};
class FruitTree {
virtual Fruit* pick() = 0;
};
class FruitEater {
virtual void eat( Fruit* ) = 0;
};
class Banana : public Fruit {};
class BananaTree {
virtual Banana* pick() { return new Banana; }
};
class BananaEater : public FruitEater {
void eat( Fruit* f ){
assert( dynamic_cast<Banana*>(f)!=0 );
delete f;
}
};
And a framework:
struct FruitPipeLine {
FruitTree* tree;
FruitEater* eater;
void cycle(){
eater->eat( tree->pick() );
}
};
Now this proves a design that's too easily broken: there's no part in the design that aligns the trees with the eaters:
FruitPipeLine pipe = { new BananaTree, new LemonEater }; // compiles fine
pipe.cycle(); // crash, probably.
You may improve the cohesion of the design, and remove the need for virtual dispatching, by making it a template:
template<class F> class Tree {
F* pick(); // no implementation
};
template<class F> class Eater {
void eat( F* f ){ delete f; } // default implementation is possible
};
template<class F> PipeLine {
Tree<F> tree;
Eater<F> eater;
void cycle(){ eater.eat( tree.pick() ); }
};
The implementations are really template specializations:
template<> class Tree<Banana> {
Banana* pick(){ return new Banana; }
};
...
PipeLine<Banana> pipe; // can't be wrong
pipe.cycle(); // no typechecking needed.
You might be able to use a variation of the curiously recurring template pattern.
class Base {
public:
// Stuff that don't depend on the input type.
};
template <typename Input>
class Middle : public Base {
public:
virtual void Foo(Input &i) = 0;
};
class Derived1 : public Middle<Derived1Input> {
public:
virtual void Foo(Derived1Input &i) { ... }
};
class Derived2 : public Middle<Derived2Input> {
public:
virtual void Foo(Derived2Input &i) { ... }
};
This is untested, just a shot from the hip!
If you don't mind the dynamic cast, how about this:
Class BaseInput;
class Base
{
public:
void foo(BaseInput & x) { foo_dispatch(x); };
private:
virtual void foo_dispatch(BaseInput &) = 0;
};
template <typename TInput = BaseInput> // default value to enforce nothing
class FooDistpatch : public Base
{
virtual void foo_dispatch(BaseInput & x)
{
foo_impl(dynamic_cast<TInput &>(x));
}
virtual void foo_impl(TInput &) = 0;
};
class Derived1 : public FooDispatch<Der1Input>
{
virtual void foo_impl(Der1Input & x) { /* your implementation here */ }
};
That way, you've built the dynamic type checking into the intermediate class, and your clients only ever derive from FooDispatch<DerivedInput>.
What you are talking about are covariant argument types, and that is quite an uncommon feature in a language, as it breaks your contract: You promised to accept a base_input object because you inherit from base, but you want the compiler to reject all but a small subset of base_inputs...
It is much more common for programming languages to offer the opposite: contra-variant argument types, as the derived type will not only accept everything that it is bound to accept by the contract, but also other types.
At any rate, C++ does not offer contravariance in argument types either, only covariance in the return type.
C++ has a lot of dark areas, so it's hard to say any specific thing is undoable, but going from the dark areas I do know, without a cast, this cannot be done. The virtual function specified in the base class requires the argument type to remain the same in all the children.
I am sure a cast can be used in a non-painful way though, perhaps by giving the base class an Enum 'type' member that is uniquely set by the constructor of each possible child that might possibly inherit it. Foo() can then check that 'type' and determine which type it is before doing anything, and throwing an assertion if it is surprised by something unexpected. It isn't compile time, but it's the closest a compromise I can think of, while still having the benefits of requiring a Foo() be defined.
It's certainly restricted, but you can use/simulate coviarance in constructors parameters.