Can I change this code to make it work? Is it possible to combine template method pattern and multiple inheritance? It seems to be very convenient to implement different algorithms in different classes. Thank you.
class TBase {
public:
virtual void Do1() const = 0;
virtual void Do2() const = 0;
void Do() const {
Do1();
Do2();
}
};
class TFirstAlgorithm {
public:
void Do1() const {}
};
class TSecondAlgorithm {
public:
void Do2() const {}
};
class TAlgorithm
: public TBase
, public TFirstAlgorithm
, public TSecondAlgorithm
{};
Fundamentally, your problem is that TFirstAlgorith::Do1 isn't related to TBase::Do1 (and likewise TSecondAlgorithm::Do2 to TBase::Do2.
One possible way to fix that would be to make them related:
class TBase {
public:
virtual void Do1() const = 0;
virtual void Do2() const = 0;
void Do() const {
Do1();
Do2();
}
};
class TFirstAlgorithm : public virtual TBase {
public:
void Do1() const { }
};
class TSecondAlgorithm : public virtual TBase {
public:
void Do2() const { }
};
class TAlgorithm
: public TFirstAlgorithm
, public TSecondAlgorithm
{};
You can use implementations for Do1 and Do2 and call appropriate algorithm inside them.
class TBase {
public:
virtual void Do1() const = 0;
virtual void Do2() const = 0;
void Do() const {
Do1();
Do2();
}
};
class TFirstAlgorithm {
public:
void Do1() const {}
};
class TSecondAlgorithm {
public:
void Do2() const {}
};
class TAlgorithm
: public TBase
, public TFirstAlgorithm
, public TSecondAlgorithm
{
virtual void Do1() const { TFirstAlgorithm::Do1() ; }
virtual void Do2() const { TSecondAlgorithm::Do2() ; }
};
Related
I provide 3 interface classes for others IA, IB, IC。 and then I need to implement these 3 interface classes. My implementation method is as follows, but the behavior of a() in the 3 classes is the same, how can I reuse the code。
class IA{
virtual void a() = 0;
};
class IB : public IA{
virtual void b() = 0;
};
class IC: public IA{
virtual void c() = 0;
};
class A :public IA{
void a(){}
};
class B :public IB{
void a(){}
void b(){}
};
class C :public IC{
void a(){}
void c(){}
};
There are several ways:
Create the common functions:
void f() { /*..*/ }
class A : public IA{
void a() override { f(); }
};
class B : public IB{
void a() override { f(); }
void b() override { /**/ }
};
class C : public IC{
void a() override { f(); }
void c() override { /**/ }
};
use virtual inheritance
class IB : public virtual IA{
virtual void b() = 0;
};
class IC : public virtual IA{
virtual void c() = 0;
};
class A : public virtual IA{
void a() override { /*..*/ }
};
class B : public A, public IB{
void b() override { /**/ }
};
class C : public A, public IC{
void c() override { /**/ }
};
Use template/CRTP
template </*typename Derived,*/ typename Base>
struct AImpl : public Base
{
void a() override { /*..*/ }
};
class A : public AImpl</*A,*/ IA> {
};
class B : public AImpl</*B,*/ IB> {
void b() override { /**/ }
};
class C : public AImpl</*C,*/ IC> {
void c() override { /**/ }
};
Use composition
class A : public IA{
void a() override { /**/ }
};
class B : public IB{
void a() override { mA.a(); }
void b() override { /**/ }
private:
A a;
};
class C : public IC{
void a() override { mA.a(); }
void c() override { /**/ }
private:
A a;
};
How can you switch between multiple sets of static methods where each set is required to have the same signature? The natural way seemed to implement a common interface, but there is no virtual static method in C++.
You can lift the static property to a single instance and use a template:
template<typename Derived>
class StaticInterface {
protected:
StaticInterface() {}
public:
virtual ~StaticInterface() {}
static Derived& instance() {
Derived theInstance;
return theInstance;
}
// The interface:
virtual void foo() = 0;
virtual void bar() = 0;
};
And use that like
class DervivedA : public StaticInterface<DerivedA> {
template<typename Derived>
friend class StaticInterface<Derived>;
DerivedA() {}
public:
virtual void foo() {};
virtual void bar() {};
};
class DervivedB : public StaticInterface<DerivedB> {
template<typename Derived>
friend class StaticInterface<Derived>;
DerivedB() {}
public:
virtual void foo() {};
virtual void bar() {};
};
Or omit the virtual part (and creation of a "costly" vtable) completely:
template<typename Derived>
class StaticInterface {
protected:
StaticInterface() {}
public:
~StaticInterface() {}
static Derived& instance() {
Derived theInstance;
return theInstance;
}
// The interface:
void foo() {
Derived::foo_impl();
}
void bar() {
Derived::bar_impl();
}
};
class DervivedA : public StaticInterface<DerivedA> {
template<typename Derived>
friend class StaticInterface<Derived>;
DerivedA() {}
public:
void foo_impl() {};
void bar_impl() {};
};
I have a class hierarchy like:
class A {
list<A*> children;
public:
void update() {
do_something();
update_current();
for(auto child : children)
children->update();
}
protected:
virtual void update_current() {};
};
class B : public A {
protected:
void update_current() override {
do_something_important();
};
};
class C1 : public B {
protected:
void update_current() override {
B::update_current();
do_something_very_important();
};
};
class C2 : public B {
protected:
void update_current() override {
B::update_current();
do_something_very_important_2();
};
};
int main() {
A* a = new A();
//fill a's childred list somehow
while(come_condition) {
//some code
a.update();
//something else
}
return 0;
}
The question is: how can I remove duplicate B::update_current(); calls from derived classes without changing program's behaviour? Is it possible or are there no solutions except calling base class functions manually? Thank you.
You could make B's children override a different function:
class B : public A {
protected:
void update_current() override final {
do_something_important();
do_something_important_later();
};
virtual void do_something_important_later() = 0;
};
With:
class C2 : public B {
protected:
void do_something_important_later() override {
do_something_very_important_2();
};
};
I am new to Design Pattern, and I'm trying the first example of (Head First Design Patterns) but I'm trying to code it in C++. I can't compile my code! I don't know why. Here's my code.
#include <iostream>
using namespace std;
class QuackBehavior
{
public:
virtual void quack();
virtual ~QuackBehavior();
};
class Quack : public QuackBehavior
{
public:
void quack()
{
cout<<"Quacking"<<endl;
}
};
class MuteQuack : public QuackBehavior
{
public:
void quack()
{
cout<<"<<< Silence >>>"<<endl;
}
};
class Squeak : public QuackBehavior
{
public:
void quack()
{
cout<<"Squeak"<<endl;
}
};
class FlyBehavior
{
public:
virtual void fly();
virtual ~FlyBehavior();
};
class FlyWithWings : public FlyBehavior
{
public:
void fly()
{
cout<<"I'm flying"<<endl;
}
};
class FlyNoWay : public FlyBehavior
{
public:
void fly()
{
cout<<"I can't fly"<<endl;
}
};
class Duck
{
public:
FlyBehavior *flyBehavior;
QuackBehavior *quackBehavior;
void display();
void performFly()
{
flyBehavior->fly();
}
void performQuack()
{
quackBehavior->quack();
}
};
class MallardDuck : public Duck
{
public:
MallardDuck()
{
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
};
int main()
{
Duck *mallard = new MallardDuck;
cout<<"Test"<<endl;
mallard->performFly();
// mallard->performQuack();
return 0;
}
Thanks for your help.
You get a compile error because you have not provided default definitions for functions in class QuackBehavior and class FlyBehavior.
Either you could provide default implementation or make the functions pure virtual.
Make the below two changes and your code should compile fine.
class QuackBehavior
{
public:
virtual void quack(){}
virtual ~QuackBehavior(){}
};
class FlyBehavior
{
public:
virtual void fly(){}
virtual ~FlyBehavior(){}
};
OR
class FlyBehavior
{
public:
virtual void fly() = 0;
};
class QuackBehavior
{
public:
virtual void quack() = 0;
};
Consider the following hierarchy:
class Base
{
virtual void Method() = 0;
virtual void Accept(Visitor *iVisitor) = 0;
};
class Derived1: public Base
{
virtual void Method(){//impl}
virtual void Accept(Visitor *iVisitor)
{
iVisitor->Visit(this);
}
};
class Derived2: public Base
{
virtual void Method(){//impl}
virtual void Accept(Visitor *iVisitor)
{
iVisitor->Visit(this);
}
};
and the visitor class:
class VisitorInterface
{
virtual void Visit(Derived1 * param);
virtual void Visit(Derived2 * param);
}
class Visitor: public VisitorInterface
{
void Visit(Derived1 * param){}
void Visit(Derived2 * param){}
}
Usually I use the visitor pattern to achieve double dispatching when the overload method depends on the parameter type, but I have only the pointer to the base class.
For example:
void foo(Visitor *visitorPtr, Base * basePtr)
{
basePtr->Accept(visitorPtr);
}
I think this is the only way to achieve double dispatching since the dynamic binding of virtual functions should happen only on the object upon which the method is called and not on its parameters (derived types).
Now I encountered a new situation, where I need a sort of Visit method overloading on multiple parameters. Something like this:
class VisitorInterfaceMultiple
{
virtual void Visit(Derived1 * param1, Derived2 * param2);
virtual void Visit(Derived2 * param1, Derived3 *param2);
}
I cannot use the classical visitor pattern solution because accept method is called on only one of the parameters.
My question is: does exist any similar visitor pattern solution, or something similar, that I could use in this situation? (I need to overload Visit with exact 2 parameters, no more than 2).
I created for you "triple" dispatch pattern: http://ideone.com/FoXNW
It is quite easy.
Main part below:
class Derived1;
class Derived2;
class Visitor;
class Base
{
public:
virtual void Accept(Visitor &iVisitor, Base& param1) = 0;
virtual void Accept(Visitor &iVisitor, Derived1& param2) = 0;
virtual void Accept(Visitor &iVisitor, Derived2& param2) = 0;
};
class Visitor
{
public:
virtual void Visit(Derived1 & param1, Derived1 ¶m2) { cout << "11\n"; }
virtual void Visit(Derived1 & param1, Derived2 ¶m2) { cout << "12\n"; }
virtual void Visit(Derived2 & param1, Derived1 ¶m2) { cout << "21\n"; }
virtual void Visit(Derived2 & param1, Derived2 ¶m2) { cout << "22\n"; }
};
class Derived1: public Base
{
public:
virtual void Accept(Visitor &iVisitor, Base& param1)
{ param1.Accept(iVisitor, *this); }
virtual void Accept(Visitor &iVisitor, Derived1& param2)
{ iVisitor.Visit(*this, param2); }
virtual void Accept(Visitor &iVisitor, Derived2& param2)
{ iVisitor.Visit(*this, param2); }
};
class Derived2: public Base
{
public:
virtual void Accept(Visitor &iVisitor, Base& param1)
{ param1.Accept(iVisitor, *this); }
virtual void Accept(Visitor &iVisitor, Derived1& param2)
{ iVisitor.Visit(*this, param2); }
virtual void Accept(Visitor &iVisitor, Derived2& param2)
{ iVisitor.Visit(*this, param2); }
};
void Visit(Visitor& visitor, Base& param1, Base& param2)
{
param2.Accept(visitor, param1);
}
Note that implementation of Derived1 and Derived2 is literally identical. You can enclose this in macro if you have more derived.