Strategy pattern on C++ - c++

I'm trying port example of Strategy pattern from HeadFirst book from java to C++
#include "iostream" using namespace std;
class IFlyBehavior
{
public:
virtual void fly() = 0;
};
class FlyWithWings : public IFlyBehavior
{
public:
void fly() override
{
cout << "fly!";
}
};
class FlyNoWay : public IFlyBehavior
{
public:
void fly() override
{
cout << "no fly!";
}
};
class IQuackBehavior
{
public:
virtual void quack() = 0;
};
class Quack : public IQuackBehavior
{
public:
void quack() override
{
cout << "Quack!";
}
};
class Squeak : public IQuackBehavior
{
public:
void quack() override
{
cout << "Squeak!";
}
};
class MuteQuack : public IQuackBehavior
{
public:
void quack() override
{
cout << "Can't quack";
}
};
class Duck : public IFlyBehavior, IQuackBehavior
{
public:
FlyWithWings* fly_behavior;
Quack* quack_behavior;
void swim()
{
cout << "Swim!";
}
virtual void display() = 0;
void performQuack()
{
quack_behavior->quack();
}
void performFly()
{
fly_behavior->fly();
}
};
class MallardDuck : public Duck
{
public:
MallardDuck()
{
quack_behavior = new Quack();
fly_behavior = new FlyWithWings();
}
void display() override
{
cout << "Mallard!";
}
};
class RedheadDuck : public Duck
{
public:
void display() override
{
cout << "RedHead!";
}
};
class DecoyDuck : public Duck
{
public:
void display() override
{
cout << "DecoyDuck!";
}
};
class RubberDuck : Duck
{
public:
void display() override
{
cout << "RubberDuck!";
}
};
int main(int argc, char* argv[])
{
Duck* md = new MallardDuck;
md->performFly();
md->performFly();
return 0;
}
But i got error:
E0322 object of abstract class type "MallardDuck" is not allowed: Duck d:\Code\CODE\C++\Duck\Duck\Source.cpp 119
It's seems like compiler not see realized classes, why this happen? Any ideas about it? How I must do?

You cannot instantiate a MallardDuck, because a MallardDuck is a Duck which supposedly implements the IQuackBehavior interface but has failed to override void Quack(). Same for the flying behaviour.
I recommend that you do not try to "translate" Java to C++; they are completely different languages and should be treated as such. Here are some good books for learning the language you're actually using.

MallardDuck inherits Duck which inherits from the abstract classes IFlyBehavior and IQuackBehavior. But nowhere do you override the abstract functions from those abstract classes.
Instead you seem to have a weird mix inheritance with encapsulation.

Related

C++ diamond problem - How to call base method only once

I'm using multiple inheritance in C++ and extending base methods by calling their base explicitly. Assume the following hierarchy:
Creature
/ \
Swimmer Flier
\ /
Duck
Which corresponds to
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Flier::print();
Swimmer::print();
std::cout << "I'm a duck" << std::endl;
}
};
Now this presents a problem - calling the duck's print method calls its respective base methods, all of which in turn call the Creature::print() method, so it ends up being called twice-
I'm a creature
I can fly
I'm a creature
I can swim
I'm a duck
I would like to find a way to make sure the base method is called only once. Something similar to the way virtual inheritance works (calling the base constructor on the first call, then only assigning a pointer to it on successive calls from other derived classes).
Is there some built-in way to do this or do we need to resort to implementing one ourselves?
If so, how would you approach this?
The question isn't specific to printing. I wondered if there's a mechanism for extending base methods and functionality while keeping the call order and avoiding the diamond problem.
I understand now that the most prominent solution would be to add helper methods, but I just wondered if there's a "cleaner" way.
Most likely this is a XY problem. But ... just don't call it twice.
#include <iostream>
class Creature
{
public:
virtual void identify()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a swimmer\n";
}
virtual void tell_ability()
{
std::cout << "I can swim\n";
}
};
class Flier : public virtual Creature
{
public:
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a flier\n";
}
virtual void tell_ability()
{
std::cout << "I can fly\n";
}
};
class Duck : public Flier, public Swimmer
{
public:
virtual void tell_ability() override
{
Flier::tell_ability();
Swimmer::tell_ability();
}
virtual void identify() override
{
Creature::identify();
tell_ability();
std::cout << "I'm a duck\n";
}
};
int main()
{
Creature c;
c.identify();
std::cout << "------------------\n";
Swimmer s;
s.identify();
std::cout << "------------------\n";
Flier f;
f.identify();
std::cout << "------------------\n";
Duck d;
d.identify();
std::cout << "------------------\n";
}
Output:
I'm a creature
------------------
I'm a creature
I can swim
I'm a swimmer
------------------
I'm a creature
I can fly
I'm a flier
------------------
I'm a creature
I can fly
I can swim
I'm a duck
------------------
We can let the base class keep track of the attributes:
#include <iostream>
#include <string>
#include <vector>
using namespace std::string_literals;
class Creature
{
public:
std::string const attribute{"I'm a creature"s};
std::vector<std::string> attributes{attribute};
virtual void print()
{
for (auto& i : attributes)
std::cout << i << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { attributes.push_back(attribute); }
std::string const attribute{"I can swim"s};
};
class Flier : public virtual Creature
{
public:
Flier() { attributes.push_back(attribute); }
std::string const attribute{"I can fly"s};
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { attributes.push_back(attribute); }
std::string const attribute{"I'm a duck"s};
};
int main()
{
Duck d;
d.print();
}
Likewise, if it is not just printing we're after, but rather the function calls, then we could let the base class keep track of the functions:
#include <iostream>
#include <functional>
#include <vector>
class Creature
{
public:
std::vector<std::function<void()>> print_functions{[this] {Creature::print_this(); }};
virtual void print_this()
{
std::cout << "I'm a creature" << std::endl;
}
void print()
{
for (auto& f : print_functions)
f();
}
};
class Swimmer : public virtual Creature
{
public:
Swimmer() { print_functions.push_back([this] {Swimmer::print_this(); }); }
void print_this()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
Flier() { print_functions.push_back([this] {Flier::print_this(); }); }
void print_this()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
Duck() { print_functions.push_back([this] {Duck::print_this(); }); }
void print_this()
{
std::cout << "I'm a duck" << std::endl;
}
};
int main()
{
Duck d;
d.print();
}
An easy way is to create a bunch of helper classes that mimick the inheritance structure of your main hierarchy and do all the printing in their constructors.
struct CreaturePrinter {
CreaturePrinter() {
std::cout << "I'm a creature\n";
}
};
struct FlierPrinter: virtual CreaturePrinter ...
struct SwimmerPrinter: virtual CreaturePrinter ...
struct DuckPrinter: FlierPrinter, SwimmerPrinter ...
Then each print method in the main hierarchy just creates the corresponding helper class. No manual chaining.
For maintainability you can make each printer class nested in its corresponding main class.
Naturally in most real world cases you want to pass a reference to the main object as an argument to the constructor of its helper.
Your explicit calls to the print methods form the crux of the issue.
One way round this would be to drop the print calls, and replace them with say
void queue(std::set<std::string>& data)
and you accumulate the print messages into the set. Then it doesn't matter those functions in the hierarchy get called more than once.
You then implement the printing of the set in a single method in Creature.
If you want to preserve the order of printing, then you'd need to replace the set with another container that respects the order of insertion and rejects duplicates.
If you want that middle class method, do not call the base class method. The easiest and simplest way is to extract extra methods, and then reimplementing Print is easy.
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
Creature::print();
detailPrint();
}
void detailPrint()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
void print()
{
Creature::Print();
Flier::detailPrint();
Swimmer::detailPrint();
detailPrint();
}
void detailPrint()
{
std::cout << "I'm a duck" << std::endl;
}
};
Without details what is your actual problem is, it hard to come up with a better solution.
Use:
template<typename Base, typename Derived>
bool is_dominant_descendant(Derived * x) {
return std::abs(
std::distance(
static_cast<char*>(static_cast<void*>(x)),
static_cast<char*>(static_cast<void*>(dynamic_cast<Base*>(x)))
)
) <= sizeof(Derived);
};
class Creature
{
public:
virtual void print()
{
std::cout << "I'm a creature" << std::endl;
}
};
class Walker : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can walk" << std::endl;
}
};
class Swimmer : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
void print()
{
if (is_dominant_descendant<Creature>(this))
Creature::print();
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer, public Walker
{
public:
void print()
{
Walker::print();
Swimmer::print();
Flier::print();
std::cout << "I'm a duck" << std::endl;
}
};
And with Visual Studio 2015 the output is:
I'm a creature
I can walk
I can swim
I can fly
I'm a duck
But is_dominant_descendant does not have a portable definition. I wish it were a standard concept.
You are asking for something like inheritance on a function level that automatically calls the inherited function and just adds more code. Also you want it to be done in a virtual way just like class inheritance. Pseudo syntax:
class Swimmer : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can swim" << std::endl;
}
};
class Flier : public virtual Creature
{
public:
// Virtually inherit from Creature::print and extend it by another line of code
void print() : virtual Creature::print()
{
std::cout << "I can fly" << std::endl;
}
};
class Duck : public Flier, public Swimmer
{
public:
// Inherit from both prints. As they were created using "virtual function inheritance",
// this will "mix" them just like in virtual class inheritance
void print() : Flier::print(), Swimmer::print()
{
std::cout << "I'm a duck" << std::endl;
}
};
So the answer to your question
Is there some built-in way to do this?
is no. Something like this does not exist in C++. Also, I'm not aware of any other language that has something like this. But it is an interesting idea...

Virtual template function in c++

I have been looking for a way to use both templating and polymorphism at the same time. Here's a simplified version of my problem:
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
//*******************************************************************
//*******************************************************************
struct DerivedStuff1
{
static void eval() { cout << "evaluating DerivedStuff1" << endl; }
};
struct DerivedStuff2
{
static void eval() { cout << "evaluating DerivedStuff2" << endl; }
};
//*******************************************************************
//*******************************************************************
class BaseClass
{
public:
template<typename StuffType> virtual void eval() const = 0;
};
class DerivedClass1 : public BaseClass
{
public:
template<typename StuffType> virtual void eval() const
{
std::cout << "We are in DerivedClass1: ";
StuffType::eval();
}
};
class DerivedClass2 : public BaseClass
{
public:
template<typename StuffType> virtual void eval() const
{
std::cout << "We are in DerivedClass2: ";
StuffType::eval();
}
};
int main()
{
BaseClass* c1 = new DerivedClass1;
c1->eval<DerivedStuff1>();
c1->eval<DerivedStuff2>();
BaseClass* c2 = new DerivedClass2;
c2->eval<DerivedStuff1>();
c2->eval<DerivedStuff2>();
return 0;
}
This code does not compile because virtual template functions are not allowed in C++. I found a few approaches to tackle this problem (CRTP, etc.) but none of them were really satisfying. Is there no elegant way to get around that issue?
The visitor pattern turns run-time polymorphism on its side and makes runtime-polymorphic function templates possible. It has other legitimate uses apart from templatisation, so I guess you can call it somewhat elegant.
Your example can look as follows:
#include <iostream>
class DerivedStuff1 {
public:
static void eval() { std::cout << "Evaluating DerivedStuff1\n"; }
};
class DerivedStuff2 {
public:
static void eval() { std::cout << "Evaluating DerivedStuff2\n"; }
};
class DerivedClass1; class DerivedClass2;
class BaseClassVisitor {
public:
virtual void visit(DerivedClass1&) = 0;
virtual void visit(DerivedClass2&) = 0;
};
class BaseClass {
public:
virtual void accept(BaseClassVisitor& v) = 0;
};
class DerivedClass1 : public BaseClass
{
public:
virtual void accept(BaseClassVisitor& v) { v.visit(*this); }
};
class DerivedClass2 : public BaseClass
{
public:
virtual void accept(BaseClassVisitor& v) { v.visit(*this); }
};
template <typename StuffType>
class EvalVisitor : public BaseClassVisitor
{
virtual void visit(DerivedClass1&) {
std::cout << "We are in DerivedClass1: ";
StuffType::eval();
}
virtual void visit(DerivedClass2&) {
std::cout << "We are in DerivedClass2: ";
StuffType::eval();
}
};
int main()
{
EvalVisitor<DerivedStuff1> e1;
EvalVisitor<DerivedStuff2> e2;
BaseClass* c1 = new DerivedClass1;
c1->accept(e1);
c1->accept(e2);
BaseClass* c2 = new DerivedClass2;
c2->accept(e1);
c2->accept(e2);
return 0;
}
Demo
Of course all shortcomings of Visitor apply here.
You could reinvent the vtable and resolve the function pointer at run time. You will, however, have to explicitely instantiate the template on the derived class, but I don't see any approach to this that won't require that.
Quick and dirty example:
#include <map>
#include <iostream>
class Base {
public:
typedef void (Base::*eval_ptr)();
using eval_vtable = std::map<std::type_index, eval_ptr>;
Base(eval_vtable const& eval_p) : eval_ptrs(eval_p) {}
template<typename T>
void eval() {
auto handler = eval_ptrs.find(type_index(typeid(T)));
if(handler != eval_ptrs.end()) {
auto handler_ptr = handler->second;
(this->*handler_ptr)();
}
}
eval_vtable const& eval_ptrs;
};
class Derived : public Base {
public:
Derived()
: Base(eval_functions) {}
template<typename T>
void eval_impl() {
std::cout << typeid(T).name() << "\n";
}
static eval_vtable eval_functions;
};
Base::eval_vtable Derived::eval_functions = {
{ type_index(typeid(int)), eval_ptr(&Derived::eval_impl<int>) },
{ type_index(typeid(float)), eval_ptr(&Derived::eval_impl<float>) },
{ type_index(typeid(short)), eval_ptr(&Derived::eval_impl<short>) },
};
int main(int argc, const char* argv[]) {
Derived x;
Base * x_as_base = &x;
x_as_base->eval<int>(); // calls Derived::eval_impl<int>()
return 0;
}
This won't be exactly fast, but it will give you the closest thing to templated virtual functions that I can think of.
Edit: For the record I don't advocate anyone use this. I would much rather revisit the design to avoid being painted in this particular corner in the first place. Please consider my answer as an academic solution to a theoretical problem, not an actual engineering recommendation.
Since virtual template methods in C++ arent allowed, you can make a class template and call static function of class template param.
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
//*******************************************************************
//*******************************************************************
struct DerivedStuff1
{
static void eval() { cout << "evaluating DerivedStuff1" << endl; }
};
struct DerivedStuff2
{
static void eval() { cout << "evaluating DerivedStuff2" << endl; }
};
//*******************************************************************
//*******************************************************************
class BaseClass
{
public:
virtual void eval() const = 0;
};
template<typename StuffType>
class DerivedClass1 : public BaseClass
{
public:
virtual void eval() const
{
std::cout << "We are in DerivedClass1: ";
StuffType::eval();
}
};
template<typename StuffType>
class DerivedClass2 : public BaseClass
{
public:
virtual void eval() const
{
std::cout << "We are in DerivedClass2: ";
StuffType::eval();
}
};
int main()
{
BaseClass* c1 = new DerivedClass1<DerivedStuff1>;
c1->eval();
c1 = new DerivedClass1<DerivedStuff2>;
c1->eval();
BaseClass* c2 = new DerivedClass2<DerivedStuff1>;
c2->eval();
c2 = new DerivedClass2<DerivedStuff2>;
c2->eval();
// deletes
return 0;
}
Output
We are in DerivedClass1: evaluating DerivedStuff1
We are in DerivedClass1: evaluating DerivedStuff2
We are in DerivedClass2: evaluating DerivedStuff1
We are in DerivedClass2: evaluating DerivedStuff2
You cannot mix templates (compile time) and polymorphic (runtime). That's it.
So, a posible workaround is remove templates. For example, it could take a function pointer or just more polymorphism:
//*******************************************************************
//*******************************************************************
struct InterfaceStuff{
virtual void eval() = 0;
}
struct DerivedStuff1 : public InterfaceStuff
{
void eval() { cout << "evaluating DerivedStuff1" << endl; }
};
struct DerivedStuff2 : public InterfaceStuff
{
void eval() { cout << "evaluating DerivedStuff2" << endl; }
};
//*******************************************************************
//*******************************************************************
class BaseClass
{
public:
virtual void eval(InterfaceStuff* interface) const = 0;
};
class DerivedClass1 : public BaseClass
{
public:
virtual void eval(InterfaceStuff* interface) const
{
std::cout << "We are in DerivedClass1: ";
interface->eval();
}
};
class DerivedClass2 : public BaseClass
{
public:
virtual void eval(InterfaceStuff* interface) const
{
std::cout << "We are in DerivedClass2: ";
interface->eval();
}
};
Another posible workaround is remove polymorphism, just use more templates:
struct DerivedStuff1
{
static void eval() { cout << "evaluating DerivedStuff1" << endl; }
};
struct DerivedStuff2
{
static void eval() { cout << "evaluating DerivedStuff2" << endl; }
};
//*******************************************************************
//*******************************************************************
class BaseClass
{
public:
template<typename Eval,typename StuffType> void eval() const
{
Eval::eval();
StuffType::eval();
}
};
class DerivedClass1 : public BaseClass
{
};
class DerivedClass2 : public BaseClass
{
};
One way of another, you have to choose one.

Exposing only the functions overriden by the derived object

I want to expose only the functions from the Abstract Class that have been overridden (implemented) by the derived Class.
For example: I have an Abstract Class called Sensor that is implemented by various different types of sensors. Some have more capabilities than others, so I don't want all functions to be exposed. Only the ones implemented. In the following example all sensors can produce DataA, but DataB and DataC are sensor specific. Some can produce all three, some 2 and some only DataA.
//Code Example
class Sensor{
public:
virtual DataContainer* getDataA() = 0; //pure virtual
virtual DataContainer* getDataB() {return null_ptr;}; //but this would appear in the derived objects
virtual DataContainer* getDataC() {return null_ptr;};
}
class SensorA : public Sensor {
public:
virtual DataContainer* getDataA(){
//code
}
}
class SensorAB : public Sensor {
public:
virtual DataContainer* getDataA(){
//code
}
virtual DataContainer* getDataB(){
//code
}
}
//main
Sensor* ab = new SensorAB();
ab->getDataB(); //GOOD
ab->getDataC(); // Not possible
Is there any way to achieve this?
You need more deep class hierarchy.
class Sensor...
class SensorA: virtual public Sensor...
class SensorB: virtual public Sensor...
class SensorAB: public SensorA, public SensorB...
Do not forget about virtual keyword.
Example:
class Sensor {
public:
virtual ~Sensor() {}
template<typename T>
bool CanConvert()
{
return dynamic_cast<T*>(this) != nullptr;
}
template<typename T>
T& Convert()
{
return dynamic_cast<T>(*this);
}
};
class SensorA: virtual public Sensor {
public:
virtual void DataA() = 0;
};
class SensorB: virtual public Sensor {
public:
virtual void DataB() = 0;
};
class SensorC: virtual public Sensor {
public:
virtual void DataC() = 0;
};
class SensorAB: public SensorA, public SensorB {
public:
void DataA() override {
std::cout << "SensorAB::DataA()" << std::endl;
}
void DataB() override {
std::cout << "SensorAB::DataB()" << std::endl;
}
};
Than you can use it:
void Func(Sensor& s)
{
if (s.CanConvert<SensorA>()) {
auto &s_a = s.Convert<SensorA>();
s_a.DataA();
}
if (s.CanConvert<SensorB>()) {
auto &s_b = s.Convert<SensorB>();
s_b.DataB();
}
if (s.CanConvert<SensorC>()) {
auto &s_c = s.Convert<SensorC>();
s_c.DataC();
}
}
...
SensorAB s_ab;
Func(s_ab);
Or you can use static polymorphysm. Create base class for every data type: SensorA, SensorB, SensorC. Than compose sensor with desired interface (SensorAB for example):
template <class Derived>
class SensorA
{
public:
void DataA() { static_cast<Derived*>(this)->DataAImpl(); }
};
template <class Derived>
class SensorB
{
public:
void DataB() { static_cast<Derived*>(this)->DataBImpl(); }
};
template <class Derived>
class SensorC
{
public:
void DataC() { static_cast<Derived*>(this)->DataCImpl(); }
};
class SensorAB: public SensorA<SensorAB>, public SensorB<SensorAB>
{
public:
void DataAImpl()
{
std::cout << "SensorAB::DataAImpl()" << std::endl;
}
void DataBImpl()
{
std::cout << "SensorAB::DataBImpl()" << std::endl;
}
};
Than you can use it:
SensorAB s_ab;
s_ab.DataA();
s_ab.DataB();
And you can use power of compilation time type check. But in this case you can cast only to SensorAB if you have base Sensor class, not in SensorA or SensorB.

Inheritance and virtual function can't compile (from Head First DP)

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;
};

Decorator pattern vs. Call super anti-pattern

Let's have a simple Decorator example:
struct IStuff {
virtual void Info()=0;
virtual ~IStuff() { }
};
class Ugly : public IStuff {
public:
void Info() { cout << "Ugly"; }
};
class Shiny : public IStuff {
IStuff* stuff;
public:
Shiny(IStuff* stuff) {
this->stuff = stuff;
}
~Shiny() {
delete stuff;
}
void Info() {
stuff->Info(); // <------------------------------- call super?
cout << "->Shiny";
}
};
int main() {
IStuff* s = new Ugly();
s = new Shiny(s); // decorate
s = new Shiny(s); // decorate more
s->Info(); // Ugly->Shiny->Shiny
delete s;
return 0;
}
Is this also the Call super anti-pattern?
Call super is a design pattern in which a particular class stipulates that in a derived subclass, the user is required to override a method and call back the overridden function itself at a particular point.
Here is a little different implementation Is there any difference in design?
This is not Call super. You call the Info method of another IStuff instance, not the overriden version.
Call super version:
struct IStuff {
// If you override this, you MUST call the base class version <-- call super
virtual void Info()
{
// a default implementation.
std::cout << "Super call ";
}
virtual ~IStuff() { }
};
class Shiny : public IStuff {
public:
void Info() {
IStuff::Info(); // don't forget to call base implementation.
std::cout << "->Shiny";
}
};
Some implementations of Decorator are making a super call to a Decorator base class, that is responsible to hold, call and manage the decorated reference:
struct IStuff
{
virtual void Info() = 0;
virtual ~IStuff() { }
};
class Stuff : public IStuff
{
public:
void Info() { std::cout << "Basic stuff"; }
};
class StuffDecorator : public IStuff
{
IStuff* decorated_;
public:
StuffDecorator(IStuff* decoratedStuff) :
decorated_(decoratedStuff) {}
~StuffDecorator() { delete decorated_; }
void Info()
{
decorated_->Info();
}
};
class Shiny : public StuffDecorator
{
public:
Shiny(IStuff* stuff) : StuffDecorator(stuff) { }
void Info()
{
StuffDecorator::Info();
std::cout << "->Shiny";
}
};
To avoid the super call you might want to combine Decorator with Template Method:
class StuffDecorator : public IStuff
{
IStuff* decorated_;
public:
StuffDecorator(IStuff* decoratedStuff) :
decorated_(decoratedStuff) {}
~StuffDecorator() { delete decorated_; }
void Info()
{
decorated_->Info();
DoInfo();
}
private:
// Template method
virtual void DoInfo() = 0;
};
class Shiny : public StuffDecorator
{
public:
Shiny(IStuff* stuff) : StuffDecorator(stuff) { }
private:
void DoInfo()
{
std::cout << "->Shiny";
}
};