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";
}
};
Related
Consider the next Example:
#include <iostream>
class Base{
public:
virtual void f() {
std::cout << "Base::f()" << std::endl;
}
};
class Derived1 : public Base
{
public:
virtual void f() override
{
Base::f();
std::cout << "Derived1::f()" << std::endl;
}
};
class Derived2 : public Base
{
public:
virtual void f() override
{
Base::f();
std::cout << "Derived2::f()" << std::endl;
}
};
class DerivedUnion : public Derived1, public Derived2
{
public:
void Derived1::f() override { // Errors
}
void Derived2::f() override { // Errors
}
};
is there some how that allow me to override the
Derived2::f()
in the
DerivedUnion{}
class?
I have tried to target specific one with namespace like style, but it didnt worked:
class DerivedUnion : public Derived1, public Derived2
// Notice DerivedUnion is not a Union, name is for
// Demostration Purposes, not intended to create
// A union Behavior
{
public:
virtual void Derived1::f() override; // Compile error
virtual void Derived2::f() override; // Compile error
virtual void f() override; // Not a compile error, but both Derived1 and Derived2 call same
};
void UseBase(Base* b){
b->f(); // expected Ambiguos call compile time
b->DerivedUnion::f() // Expected overriden DerivedUnion::f() to be called
b->Derived1::f(); // Expected overriden Derived1::f() to be called
b->Derived2::f(); // Expected overriden Derived2::f() to be called
}
An Example of it could be this one, code is self explanatory:
#include <iostream>
/* Interface Drawable */
class IDrawable {
public:
virtual void Draw() {};
};
/* Asume this is a button from one kind of bar */
class ButtonA : public IDrawable{
public:
virtual void Draw() override {
std::cout << "ButtonA::Draw()" << std::endl;
}
};
/* Asume this is a button from another kind of bar */
class ButtonB : public IDrawable{
public:
virtual void Draw() override {
std::cout << "ButtonB::Draw()" << std::endl;
}
};
/**
Where Component X is a representation that will represent 2 buttons types
*/
class ComponentX : public ButtonA, public ButtonB {
public:
void ButtonA::Draw() override { // cannot define member function ‘ButtonA::Draw’ within ‘ComponentX’
ButtonA::Draw();
std::cout << "Custom ComponentX::Draw()" << std::endl;
}
void ButtonB::Draw() override { // error: cannot define member function ‘ButtonB::Draw’ within ‘ComponentX’
ButtonB::Draw();
std::cout << "Custom ComponentX::Draw()" << std::endl;
}
};
class ComponentY : public ButtonA, public ButtonB {
public:
void ButtonA::Draw() override { // cannot define member function ‘ButtonA::Draw’ within ‘ComponentY’
ButtonA::Draw();
std::cout << "Custom ComponentY::Draw()" << std::endl;
}
void ButtonB::Draw() override { // error: cannot define member function ‘ButtonB::Draw’ within ‘ComponentY’
ButtonB::Draw();
std::cout << "Custom ComponentY::Draw()" << std::endl;
}
};
using namespace std;
void DummyAddButtonA(ButtonA* pBtnA)
{
//Add it somewhere ...
}
void DummyAddButtonB(ButtonB* pBtnB)
{
//Add it somewhere ...
}
int main()
{
ComponentX compx;
ComponentY compy;
DummyAddButtonA(&compx);
DummyAddButtonB(&compx);
DummyAddButtonA(&compy);
DummyAddButtonB(&compy);
return 0;
}
I learn C++ OOP-paradigm and want to ask related question:
Assumption
We have a base class:
class Base {
public:
virtual SomeType PowerMethod() { return SomeType{} };
}
We have a variable target and subclass which realizes some calculations with target variable based on the constructor's parameter (simple calculations or complicated calcs):
class Calc : public Base {
public: // using only public access to simplify real code structure
SomeType target;
void Simple() { target = 1; };
void Complex(){ target = 10000; };
explicit Calc(bool isSimple) {
if(isSimple)
Simple();
else
Complex();
}
};
Question
How to optimally realize two classes which based on different methods (Simple or Complex) but provide the same functionality of PowerMethod()?
My solution
class SimpleCalc : public Calc {
bool isSimple = true;
public:
SomeType PowerMethod() override {
Calc CalcInstance(isSimple);
return CalcInstance.target;
};
};
class ComplexCalc : public Calc {
bool isSimple = false;
public:
SomeType PowerMethod() override {
Calc CalcInstance(isSimple);
return CalcInstance.target;
};
};
This solution is pretty "ugly" and I want to ask you how to make it more readable.
Thank you!
I think that in your code, you didn't mean to craete a new Calc object, but instead call it on the superclass. This can be done like so:
Calc::Simple();
You can override the method PowerMethod, but still call the superclass's code:
virtual SomeType PowerMethod() override {
//do something
Base::PowerMethod();
}
If your problem is more complicated, and polymorphism and superclasses can't help you, you can always declare some method protected, so that only subclasses can access it. So, you could for example do this:
class Calc : public Base {
protected:
SomeType target;
void Simple() { target = 1; };
void Complex(){ target = 10000; };
public:
explicit Calc(bool isSimple) {
if(isSimple)
Simple();
else
Complex();
}
};
class SimpleCalc : public Calc {
public:
SomeType PowerMethod() override {
Calc::Simple();
return Calc::target;
};
};
class ComplexCalc : public Calc {
public:
SomeType PowerMethod() override {
Calc::Complex();
return Calc::target;
};
};
If your target is to learn OOP then you can use a factory design pattern to create your final calculator based on isSimple condition:
#include <iostream>
class Base
{
public:
Base()
{
target = 0;
}
int target;
virtual void PowerMethod() = 0;
};
class SimpleCalc : public Base
{
virtual void PowerMethod() { target = 0; }
};
class ComplexCalc : public Base
{
virtual void PowerMethod() { target = 1000; }
};
class CalcFactory
{
public:
virtual Base* createCalc(bool isSimple)
{
if (isSimple)
return new SimpleCalc();
else
return new ComplexCalc();
}
};
int main()
{
CalcFactory factory;
Base * base1 = factory.createCalc(true);
Base * base2 = factory.createCalc(false);
base1->PowerMethod();
base2->PowerMethod();
std::cout << base1->target << std::endl;
std::cout << base2->target << std::endl;
}
This code demonstrates the problem:
class Base
{
public:
explicit Base(std::function<void()> const& printFunc) :
_printFunc(printFunc)
{
}
void print()
{
_printFunc();
}
private:
std::function<void()> _printFunc{};
private:
virtual void _print() = 0; // If this line is commented out, then
// `Subclass1::_print()` can be called.
};
class Subclass1 : public Base
{
public:
explicit Subclass1() :
Base([this]() { _print(); })
{
}
private:
void _print() /*override*/
{
std::cout << "Subclass1\n";
}
};
class Subclass2 : public Base, public Subclass1
{
public:
using fromLowestSubclass = Base;
public:
explicit Subclass2() :
Base([this]() { _print(); }), Subclass1()
{
}
private:
void _print() /*override*/
{
// Here is the problem:
Subclass1::print(); // or: static_cast<Subclass1*>(this)->print();
std::cout << "Subclass2\n";
}
};
int main()
{
Subclass2 sc2{};
sc2.fromLowestSubclass::print();
return 0;
}
In the Subclass2::_print method, the overriding _print method of Subclass1 should be called, but instead the Subclass1::print(); statement calls the current method again. This problem can be prevented if the statement virtual void _print() = 0; is commented out.
Why use of the virtual _print method prevents me from invoking the overloaded virtual method Subclass1::_print and what solution is there so that I do not have to do without virtual methods?
class Base
{
....
private:
virtual void _print() = 0;
}
This means: you can override _print, but you can't call it, only Base has right to call it.
Now:
class Base
{
public:
void print()
{
_printFunc();
}
does that, it calls _printFunc as a virtual function, which matches current object instantiation. It doesn't meter how print() was invoked.
Adding Subclass1:: as a prefix just changes name scope and doesn't have impact how method behaves. It has only have impact on name scope.
Now if virtual method has such prefix, then selecting name scope instruct compiler that you abandoning abstraction and you need to call specific method. In such case method is called without referring to a virtual table.
Double inheritance has no impact on this issue.
You can provide a helper method which you will be able to call from ancestor:
class Subclass1 : public Base
{
....
protected:
void sub1_print() // not virtual
{
std::cout << "Subclass1\n";
}
private:
void _print() /*override*/
{
sub1_print();
}
};
class Subclass2 : public Base, public Subclass1
{
....
private:
void _print() /*override*/
{
sub1_print();
std::cout << "Subclass2\n";
}
};
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.
I'm looking for ways to avoid the "call super" code smell. This code smell is present when a subclass is required to invoke the super class's version of a virtual function when re-implementing that function.
class Base
{
public:
virtual void foo(){ ... }
}
class Derived : public Base
{
public:
virtual void foo(){ Base::foo();// required! ... }
}
If inheritance went only a single layer deep, I could use the template method
class Base
{
public:
void foo(){ ... ; foo_impl(); }
protected:
virtual void foo_impl(){}
}
class Derived : public Base
{
protected:
virtual void foo_impl(){ ... }
}
But if I need to subclass Derived, I'm back where I started.
I'm considering a registration approach.
class Base
{
public:
Base()
{
_registerCallback( [this](){ _baseFoo(); } );
}
void foo()
{
for( auto f : _callbacks )
f();
}
protected:
void registerCallback( std::function<void()> f )
{
_callbacks << f;
}
private:
void _baseFoo() { ... }
std::list< std::function<void()> > _callbacks;
}
class Derived : public Base
{
public:
Derived()
{
_registerCallback( [this](){ _derivedFoo(); } );
}
private:
virtual void _derivedFoo(){ ... }
}
Is there a more standard approach? Any problems with or improvements to this approach?
Use of
class Derived : public Base
{
public:
virtual void foo(){ Base::foo();// required! ... }
}
is the best approach IMO. I am not sure why you would consider that "code smell".
The potential for error is higher in the last approach you suggested.
It's easier to detect a missed call to Base::foo().
If all the classed derived from Base need to implement what Base::foo() does, it's better that the common code be in Base::foo(). The derived classes simply need to make the call.
For what it's worth, we use the pattern at my work a lot and it has proven to be robust over 20+ years of usage.
You can continue using template methods all the way down if you introduce new virtual member function on each level and override it on next one:
template <typename> struct tag {};
class Base
{
public:
void foo() { ... ; foo_impl(tag<Base>{}); }
protected:
virtual void foo_impl(tag<Base>) {}
};
class Derived1 : public Base
{
protected:
virtual void foo_impl(tag<Base>) override final { ... ; foo_impl(tag<Derived1>{}); }
virtual void foo_impl(tag<Derived1>) {}
};
class Derived2 : public Derived1
{
protected:
virtual void foo_impl(tag<Derived1>) override final { ... ; foo_impl(tag<Derived2>{}); }
virtual void foo_impl(tag<Derived2>) {}
};
class Derived3 : public Derived2
{
protected:
virtual void foo_impl(tag<Derived2>) override final { ... ; foo_impl(tag<Derived3>{}); }
virtual void foo_impl(tag<Derived3>) {}
};
If you dislike tag dispatch you can just give methods different names instead, perhaps something like foo_impl_N.
I consider all this overengineering.
chris mentioned a primary concern regards childs not calling their parent's corresponding member functions, this gives an idea about fixing that part:
#include <cassert>
class Base {
public:
void foo() {
foo_impl();
assert(base_foo_called && "call base class foo_impl");
}
protected:
virtual void foo_impl() { base_foo_called = true; }
private:
bool base_foo_called = false;
};
class DerivedFine : public Base {
protected:
void foo_impl() override {
Base::foo_impl();
}
};
class DerivedDerivedFine : public DerivedFine {
protected:
void foo_impl() override {
DerivedFine::foo_impl();
}
};
class DerivedDerivedNotFine : public DerivedFine {
protected:
void foo_impl() override {}
};
int main() {
DerivedFine foo;
foo.foo();
DerivedDerivedFine bar;
bar.foo();
DerivedDerivedNotFine baz;
baz.foo(); // this asserts
}
CRTP can solve everything.
For each foo method, you implement an empty non-virtual foo_before() that does nothing in your CRTP helper.
CRTP helper takes a derived and a base. Its virtual void foo() invokes static_cast<Derived*>(this)->foo_before() then Base::foo() then after_foo().
struct Base {
virtual void foo() { std::cout << "foo\n"; }
virtual ~Base() {};
};
template<class D, class B=Base>
struct foo_helper:B {
virtual void foo() {
static_cast<D*>(this)->before_foo();
this->B::foo();
static_cast<D*>(this)->after_foo();
}
private:
void before_foo() {}; void after_foo() {};
};
struct Derived1 : foo_helper<Derived1> {
void before_foo() { std::cout << "before1\n"; }
};
struct Derived2 : foo_helper<Derived2> {
void before_foo() { std::cout << "before2\n"; }
void after_foo() { std::cout << "after2\n"; }
};
struct DoubleDerived : foo_helper<DoubleDerived, Derived2> {
void after_foo() { std::cout << "even more after\n"; }
};
int main() {
std::cout << "---- Derived1\n";
Derived1 d1;
d1.foo();
std::cout << "---- Derived2\n";
Derived2 d2;
d2.foo();
std::cout << "---- DoubleDerived\n";
DoubleDerived dd;
dd.foo();
}
Live example.
Output:
---- Derived1
before1
foo
---- Derived2
before2
foo
after2
---- DoubleDerived
before2
foo
after2
even more after
Here's an idea inspired by this answer
The idea is to use the fact that constructors and destructors of a struct / class provides a sort of "pre/post function calling" mechanism that gets inherited. So instead of doing the pre/post function calls in the virtual method itself, we can use a functor and define the pre/post function call in the constructor / destructor. That way, functors that inherit from the base functor will inherit the pre/post function call.
Code
struct BasePrePostFunctor
{
BasePrePostFunctor()
{
printf("Base pre-func\n");
}
virtual void operator()()
{
printf("Base Main func\n");
}
~BasePrePostFunctor()
{
printf("Base post-func\n");
}
};
struct DerivedPrePostFunctor : BasePrePostFunctor
{
DerivedPrePostFunctor()
{
printf("Derived pre-func\n");
}
void operator()() override
{
printf("Derived main func\n");
}
~DerivedPrePostFunctor()
{
printf("Derived post-func\n");
}
};
class BaseClass
{
public:
virtual void virtual_func()
{
BasePrePostFunctor func;
func();
}
};
class DerivedClass : public BaseClass
{
public:
void virtual_func() override
{
DerivedPrePostFunctor func;
func();
}
};
int main(int argc, char** argv)
{
DerivedClass derived;
derived.virtual_func();
};
Output
Base pre-func
Derived pre-func
Derived main func
Derived post-func
Base post-func