Design of a general-purpose handler for 'solver' class - c++

A case where 'problem' should not be a problem in the title.
I want to implement a solver (class Solver) for a collection of problems (all children of class Problem), which more or less share the same set of methods. My current design is like this:
In solver.h:
template<class P>
class Solver{
public:
P* p;
Solver(P* problem) : p(problem) {}
void justDoIt(){
p->step1();
p->step2();
p->step3();
p->step4();
p->step5();
}
}
In main.cpp:
#include "solver.h"
class A {
public:
void step1() {}
void step2() {}
void step3() {}
void step4() {}
void step5() {}
};
class B: public A {
public:
void step2() {}
void step4() {}
};
class C: public A {
public:
void step3() {}
void step4() {}
void step5() {}
};
int main(){
B b;
C c;
Solver<B> sb(&b);
Solver<C> sc(&c);
sb.justDoIt();
sc.justDoIt();
return 0;
}
If I want to extend Solver for a new problem type, say C, and it
does nothing in step1();
does step2.5() between step2() and step3()
Now calling C c; Solver<C> sc(&c); c.justDoIt(), I need to modify A, B and Solver::justDoIt() first.
Is there a scalable to design the interface that adding new problem types (all childern of A) for Solver?
PS: The current codebase I am about to modify has 47 types of problems all using the same Solver class. Minimal change is preferred.
How can I do it better?

At least to me this design seems like a (pardon the technical jargon) mess.
Right now, Solver has intimate knowledge of the internals of Problem. Further, it appears there's no way for Solver to do its job without intimate knowledge of the internals of Problem either.
At least in my estimation, what you've called Solver::justDoIt() should really be Problem::operator(). If many of the Problems use step1() through step5() as you've shown in Solver, you can provide that implementation by default in Problem itself, then those that need to override that will provide their own implementations:
class Problem {
protected:
virtual void step1() {}
// ...
virtual void step5() {}
public:
virtual void operator()() {
step1();
step2();
step3();
step4();
step5();
}
};
class B : public Problem {
protected:
void step2() {}
void step4() {}
};
class C : public Problem {
protected:
virtual void step3() {}
virtual void step4() {}
virtual void step5() {}
};
Then the main looks something like this:
int main() {
B b;
C c;
b();
c();
}
Or, if you prefer shorter code:
int main() {
B()();
C()();
}
This creates a temporary object of each type, then invokes the operator() on that temporary object. I'm not particularly fond of it, but some people think it's great.

Virtual Functions:
The first option that should come into mind is to use virtual functions:
Redefine your Problem-class to contain a pure virtual function (that means: every child needs to reimplement it):
class Problem{
public:
virtual void allSteps()=0;
};
Redefine your Solver to call this special function:
class Solver{
public:
Problem* p;
Solver(Problem* prob):p(prob){}
void solve(){
p->allSteps();
}
};
And add an implementation in every child-class:
class MyProblem: public Problem{
public:
void step1(){
std::cout << "step1\n";
}
void step2(){
std::cout << "step1\n";
}
void stepx(int x){
std::cout << "step"<<x<<"\n";
}
void allSteps(){
step1();
step2();
stepx(3);
stepx(4);
}
};
And use your main-function as you did before:
int main() {
MyProblem myP;
Solver s(&myP);
s.solve();
return 0;
}
Try it here: http://ideone.com/NOZlI6
Function-Pointers/Objects
This is a slightly more complex solution, but depending on your needs (e.g. executing only a single step and then do something else) it might better fit your needs.
Whenever you see something like "foo1","foo2","foo3",... you should think of an array or a vector. And the same can be applied to your Problem:
First of all, redefine your "Problem" class to take an arbitrary amount of function pointers - or using c++, function objects:
class Problem{
public:
std::vector<std::function<void(void)>> functions;
};
Then all your Solver needs to do is to iterate over the function objects inside your Problems class:
class Solver{
public:
Problem* p;
Solver(Problem* prob):p(prob){}
void solve(){
for(auto func : p->functions)
func();
}
};
In order to register your classes functions properly, you need to remember that member-functions have an additional "hidden" parameter "this" that is a pointer to the class itself. But we can use std::bind to make a void(void) function out of any function we have. An alternative would be to use static functions, but since this should be easy to figure out, i will use the more complex way here:
class MyProblem: public Problem{
public:
void step1(){
std::cout << "step1\n";
}
void step2(){
std::cout << "step1\n";
}
void stepx(int x){
std::cout << "step"<<x<<"\n";
}
MyProblem(){
functions.push_back(std::bind(&MyProblem::step1,this));
functions.push_back(std::bind(&MyProblem::step2,this));
functions.push_back(std::bind(&MyProblem::stepx,this,3));
functions.push_back(std::bind(&MyProblem::stepx,this,4));
}
};
Your main-function will then be unaffected:
int main() {
MyProblem myP;
Solver s(&myP);
s.solve();
return 0;
}
Try it here: http://ideone.com/BmIYVa

Related

Implementing compositional behaviour for virtual methods

Suppose that I have a heirarchy of several classes:
class A {
public:
virtual void DoStuff() = 0;
};
class B : public A {
public:
// Does some work
void DoStuff() override;
};
class C : public B {
public:
// Calls B::DoStuff and does other work
void DoStuff() override;
};
It can naively be implemented:
void Derived::DoStuff() {
Base::DoStuff();
...
}
This implementation has a serious problem, I believe: one always has to remember to call base implementation when overrides.
Alternative:
class A {
public:
void DoStuff() {
for (auto& func: callbacks_) {
func(this);
}
}
virtual ~A() = default;
protected:
template <class T>
void AddDoStuff(T&& func) {
callbacks_.emplace_back(std::forward<T>(func));
}
private:
template <class... Args>
using CallbackHolder = std::vector<std::function<void(Args...)>>;
CallbackHolder<A*> callbacks_;
};
Usage:
class Derived : public Base {
public:
Derived() {
AddDoStuff([](A* this_ptr){
static_cast<Derived*>(this_ptr)->DoStuffImpl();
});
}
private:
void DoStuffImpl();
};
However, I believe that it has a good amount of overhead when actually calling DoStuff(), as compared to the first implementation. In the use cases which I saw, possibly long costruction of objects is not a problem (one might also try to implement something like "short vector optimization" if he wants).
Also, I believe that 3 definitions for each DoStuff method is a little too much boilerplate.
I know that it can be very effectively solved by using inheritance pattern simular to CRTP, and one can hide the template-based solution behind interface class (A in the example), but I keep wondering -- shouldn't there be an easier solution?
I'm interested in a good implementation of call DERIVED implementation FROM BASE, if and only if derived class exists and it has an overriding method for long inheritance chains (or something equivalent).
Thanks!
Edit:
I am aware of an idea described in #Jarod42's answer, and I don't find it appropriate because I believe that it is ugly for long inheritance chains -- one has to use a different method name for each level of hierarchy.
You might change your class B to something like:
class A {
public:
virtual ~A() = default;
virtual void DoStuff() = 0;
};
class B : public A {
public:
void DoStuff() final { /*..*/ DoExtraStuff(); }
virtual void DoExtraStuff() {}
};
class C : public B {
public:
void DoExtraStuff() override;
};
I am not sure if I understood correctly but this seems to be addressed pretty good by the "Make public interface non-virtual, virtualize private functions instead" advice.
I think it's orignated in the Open-Closed principle. The technique is as-follows:
#include <iostream>
class B {
public:
void f() {
before_f();
f_();
};
private:
void before_f() {
std::cout << "will always be before f";
}
virtual void f_() = 0;
};
class D : public B{
private:
void f_() override {
std::cout << "derived stuff\n";
}
};
int main() {
D d;
d.f();
return 0;
}
You essentially deprive descendant class of overriding public interface, only customize exposed parts. The base class B strictly enforces that required method is called before actual implementation in derived might want to do. As a bonus you don't have to remember to call base class.
Of course you could make f virtual as well and let D decide.

Structuring reusable code

I have a class that does something similar to:
class B{
void x(){
statement-block1;
statement-block2;
statement-block3;
statement-block4;
}
void y(){
statement-block5;
statement-block6;
statement-block7;
statement-block8;
}
}
I need to add a new class that does this:
class C{
void x(){
statement-block1;
statement-block200;
statement-block3;
statement-block4;
}
void y(){
statement-block5;
statement-block6;
statement-block700;
statement-block8;
}
}
I was considering combining the reusable logic this way:
class A{
void x(){
statement-block1;
statement-block2;
u();
statement-block4;
}
void y(){
statement-block5;
statement-block6;
v();
statement-block8;
}
virtual void u(){
default-message;
}
virtual void v(){
default-message;
}
}
class B : A{
void u(){
statement-block3;
}
void v(){
statement-block7;
}
}
class C : A{
void u(){
statement-block200;
}
void v(){
statement-block700;
}
}
Is there a better way to implement this, a different/better way of injecting sub-class-specific code, or is there a design pattern I can use? In the future, I might have to add more classes similar to B and C.
Thanks!
It depends what you are trying to achieve. If the statements block are likely to change in run time (dynamic) then use virtual pointer as you showed in your example, however if those are not dynamic, then pass a template parameter instead, in that way you don't pay for what you don't use (virtual pointer). i.e.
class B
{
public:
template <typename T>
void x(T f)
{
f();
}
};
void g(){ std::cout << "value" << std::endl;}
int main()
{
B b {};
b.x(g);
}
Your approach looks great. It applied KISS which is most often the best design pattern to use! You could do this
virtual void u(){
default-message;
}
virtual void v(){
u();
}
But that's up to you I guess
Another option is to combine all classes and use std function or a function pointer for that function call that changes.

Must Invoke first design pattern

I am looking for an elegant solution for my case. I tried to find a design pattern that specified and offers solution for this case but i failed to find one.
I have a base class that uses to store general object and later Invoke it.
I want the execution will be separated into two parts:
A must have part which will always take place (do1st()).
User defined code (do2nd()).
For example:
class InvokeBase
{
public:
InvokeBase(void *ptr) : context_(ptr) {}
virtual ~InvokeBase () {}
void operator()() = 0;
protected:
void do1st() {//Mandatory code to execute for every InvokeBase type when calling operator()};
void * context_;
};
class InvokeDerived : public InvokeBase
{
public:
InvokeDerived(void *ptr) : base(ptr){}
virtual ~InvokeDerived();
void do2nd() {//User defined code}
void operator()()
{
do1st(); // << How to force this execution?
do2nd();
}
};
void main()
{
InvokeBase *t = new InvokeDerived();
t(); // << here i want the execution order will be do1st and then do2nd.
}
The trick is that i want do1st will execute always, that i will not have to call it from InvokeDerived. I want to allow the user to inherit from InvokeBase with the guarantee that do1st will always be called when invoking the operator().
This is the template method pattern: split a function with semi-flexible behavior accross the class hierarchy into multiple parts, and make virtual only the ones that change:
class InvokeBase
{
public:
InvokeBase(void *ptr) : context_(ptr) {}
virtual ~InvokeBase () {}
void operator()() // this is non-virtual (this is the template method)
{
do1st();
do2nd(); // this resolves to virtual call
}
protected:
void do1st() { /* fixed code here */ };
virtual void do2nd() = 0; // variable part here
void * context_;
};
class InvokeDerived : public InvokeBase
{
public:
InvokeDerived(void *ptr) : base(ptr){}
virtual ~InvokeDerived() = default;
protected:
void do2nd() override
{
// code speciffic to InvokeDerived here
}
};

Namespace-like access in class

For a container class I'd like to provide an interface with several functions which are grouped into categories, for example:
Data::Get::FirstGetter()
Data::Get::SecondGetter()
Data::Set::FirstSetter()
Data::Set::FirstSetter()
This would allow for something like this:
Data myData;
myData::Set::FirstSetter( stuff );
std::cout << myData::Get::FirstGetter() << std::endl; // -> "stuff"
Obviously the code itself is bogus and I've used the scope operator :: as a potential placeholder for something else (I am aware that you can not create namespaces within a class).
An approach to achieve something like this is demonstrated in the following snippet:
#include <iostream>
struct Foo {
private:
struct aBar {
void IFunc(){
std::cout << "IFunc()" << std::endl;
}
};
public:
void OFunc(){
std::cout << "OFunc()" << std::endl;
}
aBar Bar;
};
int main(){
Foo foo;
foo.OFunc();
foo.Bar.IFunc();
}
However, in order to use this, one must create an instance of each grouping object (in the pseudocode example one instance of Get and another one of Set, in the dummy example one instance of aBar). Is there a way to achieve this functionality in a different way (maybe using the actual scope operator :: to indicate the member that is to be called resides within an inner scope)?
I don't really understand the reason why you want to achieve such a behaviour. However, if you want to achieve something like that you may get inspired by the following (although I won't ever use some code like this in any project, still not seeing one plausible reason):
#include <iostream>
class Interface1
{
protected:
virtual ~Interface1() {}
virtual void DoStuff1() = 0;
};
class Interface2
{
protected:
virtual ~Interface2() {}
virtual void DoStuff2() = 0;
};
class Interface3
{
protected:
virtual ~Interface3() {}
virtual void DoStuff3() = 0;
};
class Container;
class Grouper1
{
public:
static void DoStuff1(Container& arContainer);
static void DoStuff2(Container& arContainer);
};
class Grouper2
{
public:
static void DoStuff3(Container& arContainer);
};
class Container : public Interface1, public Interface2, public Interface3
{
public:
virtual ~Container() {}
private:
friend class Grouper1;
friend class Grouper2;
virtual void DoStuff1() { printf("DoStuff1()\n"); }
virtual void DoStuff2() { printf("DoStuff2()\n"); }
virtual void DoStuff3() { printf("DoStuff3()\n"); }
};
void Grouper1::DoStuff1(Container& arContainer) { arContainer.DoStuff1(); }
void Grouper1::DoStuff2(Container& arContainer) { arContainer.DoStuff2(); }
void Grouper2::DoStuff3(Container& arContainer) { arContainer.DoStuff3(); }
int main(int aArgc, char** aArgv)
{
Container c;
Grouper1::DoStuff1(c);
Grouper1::DoStuff2(c);
Grouper2::DoStuff3(c);
return 0;
}
This way your Container can implement some interfaces and your Groupers provide static functions (grouped) to access those methods (although you need to pass the actual Container, you want to work on). But definitely you won't achieve namespace-like access if you don't provide some helper functions/classes (as Grouper1, Grouper2).

Is there no way to upcast into an abstract class and not modify it each time a class is derived from it?

#include<iostream>
using namespace std;
class Abs
{
public:
virtual void hi()=0;
};
class B:public Abs
{
public:
void hi() {cout<<"B Hi"<<endl;}
void bye() {cout<<"B Bye"<<endl;}
};
class C:public Abs
{
public:
void hi() {cout<<"C Hi"<<endl;}
void sayonara() {cout<<"C Sayonara"<<endl;}
};
int main()
{
Abs *bb=new B;
bb->bye();
Abs *cc=new C;
cc->sayonara();
}//main
The compiler says
test2.cpp: In function ‘int main()’:
test2.cpp:26: error: ‘class Abs’ has no member named ‘bye’
test2.cpp:28: error: ‘class Abs’ has no member named ‘sayonara’
Because of this problem, I'll have to add functions to the Abs class each time I create a new derived class which inherits from it (Upcasting is compulsory for me to do. The program I'm planning requires it to be so). I don't want to touch the base class once it's created.
Doesn't this problem violate the principle that once you make a base class, you won't have to modify it ever. Any way to resolve this problem?
p.s: I've seen the factory design pattern and the prototype design patterns, but both of them can't seem to be able to solve it.
This is defeating the purpose of inheritance and abstract interfaces. bye and sayonara both do the same thing (saying goodbye), only in different languages. This means you should have an abstract say_goodbye method that gets overridden for subclasses. I suppose this is a simplified example, so maybe you could describe your actual scenario so we can provide more specific help.
Edit If you want to create a copy of the derived class through an abstract interface, check out this question. If you want to explicitly access the different attributes of your subclasses, you should be asking your self if subclassing es even appropriate here, since your classes don't seem to have much in common.
Well, i'm not sure to understand exactly what you want (and why you want it that way) but:
int main()
{
Abs *bb=new B;
static_cast<B*>(bb)->bye();
Abs *cc=new C;
static_cast<C*>(cc)->sayonara();
}//main
Will work.
You just have to be sure that bb is really a B* before you static_cast.
You may also use dynamic_cast which will return a null pointer if bb is not of the correct type.
int main()
{
B *bb = new B;
bb->bye();
C *cc=new C;
cc->sayonara();
}//main
This way modifications in the base class are no longer needed :)
Dynamic casting is a sensible option. If you're religious about dynamic casts, you can use the visitor design pattern:
struct Abs;
struct B;
struct C;
struct Visitor
{
virtual ~Visitor() {}
// Provide sensible default actions
virtual void visit(Abs&) const { throw "not implemented"; }
virtual void visit(B& b) const { visit(static_cast<Abs&>(b)); }
virtual void visit(C& c) const { visit(static_cast<Abs&>(c)); }
};
struct Abs
{
virtual ~Abs() {}
virtual void hi() = 0;
virtual void accept(Visitor const& v) { v.visit(*this); }
};
struct B : Abs
{
void hi() { ... }
void accept(Visitor const& v) { v.visit(*this); }
void bye() { ... }
};
struct C : Abs
{
void hi() { ... }
void accept(Visitor const& v) { v.visit(*this); }
void sayonara() { ... }
};
struct DoSayonara : Visitor
{
void visit(C& c) const { c.sayonara(); }
};
struct DoBye : Visitor
{
void visit(B& b) const { b.bye(); }
};
struct ByeOrSayonara : Visitor
{
void visit(B& b) const { b.bye(); }
void visit(C& c) const { c.sayonara(); }
};
and then you use
Abs* b = new B(); Abs* c = new C();
b->accept(DoSayonara()); // Throw an exception
c->accept(DoSayonara()); // Do what is expected
Do this only when you really need it.
If upcasting is compulsory and you need to call methods defined in the subclasses then You're Doing It Wrong.
However, at a given point in time, you either know that an object is a specific subclass, in which case you can dynamically cast to that type, or you don't and can't be sure you can call the function.
Assuming this is related to your other question, I've tried to explain a way to implement that particular problem in a different manner there.