enforce order of function calls? - c++

Say I have a abstract base class and I want to have a pure virtual method which must be implemented by the derived class but I want to make sure that the derived method calls functions in a particular order what could I do to enforce it ?
I.E
base class
virtual void doABC()=0;
virtual void A()=0;
virtual void B()=0;
virtual void C()=0;
// must call ABC in the correct order
derived class public base
void doABC();
This is just so I have a better understanding on how to design my classes to enforce someone to use my class correctly.

You're looking for the template method pattern:
http://en.wikipedia.org/wiki/Template_method_pattern
Something along these lines:
class BaseAlgorithm
{
protected:
virtual void firstStep() = 0;
virtual void secondStep() = 0;
virtual void finalStep() = 0;
public:
void runAlgorithm()
{
firstStep();
secondStep();
finalStep();
}
};
class ConcreteAlgorithm : BaseAlgorithm
{
virtual void firstStep() {};
virtual void secondStep() {};
virtual void finalStep() {};
};
You basically force extending classes to implement all intermediate steps, but you keep them protected or private - document this - and only call runAlgorithm(), which ties the smaller pieces together.

There are actually two particular ways, depending on whether you go with inheritance or parameterization.
If you with inheritance, it is the Template Method pattern:
class Base {
public:
void doit() {
this->do1();
this->do2();
}
private:
virtual void do1() = 0;
virtual void do2() = 0;
};
And if you go with parameterization, it is the Strategy pattern:
class Strategy {
public:
virtual void do1() = 0;
virtual void do2() = 0;
};
void doit(Strategy& s) {
s.do1();
s.do2();
}
From the website:
Strategy is like Template Method except in its granularity. [Coplien, C++ Report, Mar 96, p88]
Template Method uses inheritance to vary part of an algorithm. Strategy uses delegation to vary the entire algorithm. [GoF, p330]
Strategy modifies the logic of individual objects. Template Method modifies the logic of an entire class. [Grand, p383]
I recommend you familiarize yourself with them.

The simplest answer could be if You remove virtual from doABC(), so that it can not be derived by child class. Call the virtual methods inside doABC() in correct order.

Related

Diamond inheritence - Inheriting from an abstract class and also a concrete class than implements a shared based class

Please Consider:
IReferenceCounting is a pure abstract class, with methods AddRef and RemoveRef
virtual void AddRef() noexcept = 0;
virtual void RemoveRef() noexcept = 0;
I did not build this class, nor can I change it.
Now I have another class, which I did build, called ISoundComponent that inherits from IReferenceCounting. Class ISoundComponent is also abstract (for a start it doesn't contain a definition for AddRef or Release).
As every component that inherits from IReferenceCounted will need to implement AddRef and RemoveRef, there exists ReferenceCountedImpl, which inherits from IReferenceCounted. I did not build this class and I cannot change it.
Finally, I have another class I did build, say SoundDiagnostics, which inherits from ISoundComponent and ReferenceCountedImpl
Many have you have already seen it - I have a diamond inheritance problem. By not providing my own AddRef and RemoveRef, and instead using ReferenceCountedImpl, means I would need ISoundComponent and ReferenceCountedImpl to inherit virtually from IReferenceCounted... correct?
Unfortunately I cannot edit ReferenceCountedImpl only ISoundComponent . This is because IReferenceCounting and ISoundComponent live across many projects in our codebase but ReferenceCountedImpl lives inside only a single project (the same project SoundDiagnostics lives). This makes sense, as a project can decide on how it wants to implement the IReferenceCounting, and we should be able to reuse it inside different classes in that project.
Unfortunately, as I cannot go and edit ReferenceCountedImpl, I cannot build this, due to the diamond inheritance problem (SoundDiagnostics won't know whether to call ReferenceCountedImpl::AddRef or ISoundComponent ::AddRef).
I feel like I'm barking up the wrong tree, missing something obvious, getting caught up in the details of virtual inheritance and/or and my design is messed up. The codebase organization should be agnostic to this problem. Can anyone give me some guidance on how this should be architected? I don't think ReferenceCountedImpl inheriting virtually from IReferenceCounted is the solution - e.g. there are performance reasons to consider when doing this.
Interested to learn how to tackle this.
EDIT:
// available across all projects in code base
class IReferenceCounted
{
virtual void AddRef() = 0;
virtual void RemoveRef() = 0;
};
// available across a few select projects in the codebase (ones that wish to use some kind of sound component)
class ISoundComponent : public virtual IReferenceCounted
{
virtual void Play() const = 0;
};
// available within one specific project, SoundDiagnostics. I cannot modify this
class ReferenceCountedImpl : public IReferenceCounted
{
void AddRef() override
{
m_refcount++;
}
void RemoveRef() override
{
if (--m_refcount == 0)
{
delete this;
}
}
int m_refcount = 0;
};
// available within one specific project, SoundDiagnostics.
class SoundDiagnostics : public ISoundComponent, public ReferenceCountedImpl
{
void Play() const override
{
return;
}
void RunDiagnostics()
{
}
};
// function within my SoundDiagnostics project
int main()
{
SoundDiagnostics soundDiagnostics;
return 0;
}
Trying to compile this will produce
object of abstract class type "SoundDiagnostics" is not allowed:
pure virtual function "IReferenceCounted::AddRef" has no overrider
pure virtual function "IReferenceCounted::RemoveRef" has no overrider
If ReferenceCountedImpl inherits virtually from IReferenceCounted then this code compiles successfully.
I tried to turn your description into code. It works.
class IReferenceCounting {
public:
virtual void AddRef() const noexcept = 0;
virtual void RemoveRef() const noexcept = 0;
};
class IComponentPublicHeader :public virtual IReferenceCounting {};
class ReferenceCountedImpl :public virtual IReferenceCounting {
public:
void AddRef() const noexcept override {};
void RemoveRef() const noexcept override {};
};
class MyAmazingClass : IComponentPublicHeader, ReferenceCountedImpl {
MyAmazingClass() {
AddRef();// ReferenceCountedImpl::AddRef
}
};
Update:I read your code snippet.If AddRef and RemoveRef is public,You can try to implement your class like this.
class SoundDiagnostics : public ISoundComponent, public ReferenceCountedImpl
{
void Play() const override
{
return;
}
void AddRef() override
{
ReferenceCountedImpl::AddRef();
}
void RemoveRef() override
{
ReferenceCountedImpl::RemoveRef();
}
void RunDiagnostics()
{
}
};
If AddRef and RemoveRef is private,let ISoundComponent not inherit the IReferenceCounted.
class ISoundComponent
{
virtual void Play() const = 0;
};

Classes design with virtual methods

How would someone solve such a problem with classes and type as least as possible code?
Here is what I have
Base interface for everything
class IWindow
{
public:
virtual void Refresh() = 0;
// another 100 virtual methods
// ...
};
This interface is used inside a library that has no idea about the concrete implementation.
Here is a version of the concrete implementation
class ConcreteWindow : public IWindow
{
public:
void Refresh() override {}
/// the other 100 overridden methods
};
Now we have another interface that adds some additional methods and also used inside that library.
class IDBDetail : public IWindow
{
public:
virtual void DoDetail() = 0;
};
and here is the main problem, when we create the concrete inmplementation for it
class IGDBDetailWrapper : public IDBDetail, public ConcreteWindow
{
public :
void DoDetail() {}
};
of course the concrete class IGDBDetailWrapper is abstract as well because it doesn't implement those 100 methods, but I don't wanna do that, I'd like just to reuse the implementation from ConcreteWindow, they are all working with the same window handle but this won't compile of course.
I can copy/paste those 100 methods from ConcreteWindow into IGDBDetailWrapper, but that's an overkill, cause I might have another 10 such new interfaces and concrete implementations.
What other pattern can I use here that would help solve the question and not re-implement those 100 methods again and again?
Thx
Your design is running into diamond problem.
Now we have another interface that adds some additional methods and
also used inside that library.
class IDBDetail : public IWindow {
public:
virtual void DoDetail() = 0;
};
From the description of your IDBDetail interface looks like IDBDetail should not inherit from IWindow. If its just about adding additional functionality then IDBDetail need not be a IWindow. It just needs to understand the IWindow. For example in order to make a monkey do a special things, a trainer need not be a monkey.
Decorator pattern may be what you are looking for.
First, if you are using Visual Studio there are refactoring tools that can help you with that automating what could be otherwise a tedious task, second:
To me is much pointless doing the same:
class IDBDetail : public IWindow
{
public:
virtual void DoDetail() = 0;
};
I would do that instead
class IDBDetail
{
public:
virtual void DoDetail() = 0;
};
Interfaces should be used to abstract away responsibilities, so cluttering a Interface with already hundreds of methods with additional methods is a symptom of bad design.
However you could leverage composition one time for all, so you create one time a class that resolve the problem for your, and you can later reuse that
class IDBDetailWithConcreteWindow: public IDBDetail{
IWindow * concreteWindow;
public:
IDBDetailWithConcreteWindow(IWindow * window){
concreteWindow = window;
}
void Refresh() override{
concreteWindow->Refresh();
}
}
And finally in any derived class you have just to implement methods from IDBDetail
IGDBDetailWrapper: public IDBDetailWithConcreteWindow{
public:
void DoDetail() override { }
}
The advantage with this solution is that if you have external constraints (like a bad designed pre-existing code base) you can still use it, while the upper solution will not work if you cannot change the IDBDetail interface.
#bashrc is right, but it should be possible to solve the problem with virtual inheritance:
class ConcreteWindow : public virtual IWindow {...}
class IDBDetail : public virtual IWindow {...}
This Wikipedia article on virtual inheritance states the solution as well.
You can use virtual inheritance. If we ignore fact should IDBDetail inherit from IWindow or not, we could use virtual inheritance to solve problem with current architecture:
class IWindow
{
public:
virtual void Refresh() = 0;
// another 100 virtual methods
// ...
};
class ConcreteWindow : virtual public IWindow
{
public:
void Refresh() override {}
/// the other 100 overridden methods
};
class IDBDetail : virtual public IWindow
{
public:
virtual void DoDetail() = 0;
};
class IGDBDetailWrapper : public IDBDetail, public ConcreteWindow
{
public :
void DoDetail() {}
};
Now compiler will use implementation for your 101 abstract method from ConcreteWindow
You have to override all the methods in abstract class, there is no other way. Actually you shouldn't create an abstract class of 100 methods here and that's it. Perhaps You can divide it in some smaller abstract classes? However, in this case IDBDetail should not inherit after IWindow and IGBDDetailWrapper also shouldn't inherit after IWindow - and we are here.
It will not solve your problem, but at least you can redirect execution yourself:
class IGDBDetailWrapper : public IDBDetail, public ConcreteWindow
{
public:
virtual void DoDetail() override { /*work here*/ }
virtual void Refresh() override { ConcreteWindow::Refresh(); }
//another 100 methods
};
You can make the block of such redirections as a compiler #DEFINE and repeat it as many times as you want.

C++ template method and obtaining result - design

I've such an interface class:
class MyInterface
{
public:
virtual void DoStuff() = 0;
virtual Result GetResult() = 0;
};
and simple abstract method, which realizes template pattern:
class Abstract: public MyInterface
{
public:
void DoStuff()
{
DoAFoo();
BakeAPie();
PrepareResult();
}
virtual DoAFoo() = 0;
virtual BakeAPie() = 0;
virtual PrepareResult() = 0;
};
And here comes my question. The method GetResult() should be implemented by every concrete implementation of Abstract? There would be a lot of such subclasses.
Or it should be handled in the Abstract class? Like this:
class Abstract: public MyInterface
{
public:
....
GetResult()
{
return m_result;
}
private:
Result m_result;
}
But how can I ensure, that Abstract subclasses will fill m_result within PrepareResult()?
You should ask yourself this question: "Is storing the result in a member and returning that member from GetResult() the only sane implementation of GetResult()? Some generally possible alternatives could be:
Compute the result on demand each time GetResult() is called.
Caching more than one result somewhere and returning the proper one from GetResult() based on circumstances.
Something else...?
Without knowing your exact problem, we cannot answer this, only you can.
If you arrive at the conclusion that yes, storing a single result in a member and returning it is the only sane approach, you can go ahead and implement GetResult() in Abstract, because then everybody else would be doing the exact same thing anyway. And to guarantee correct behaviour of PrepareResult(), you can change the interface as follows:
class Abstract: public MyInterface
{
public:
void DoStuff()
{
DoAFoo();
BakeAPie();
m_result = PrepareResult();
}
virtual void DoAFoo() = 0;
virtual void BakeAPie() = 0;
virtual Result PrepareResult() = 0;
virtual Result GetResult()
{ return m_result; }
private:
Result m_result;
};
Note that I'd suggest you mark GetResult() as const in MyInterface (and so in Abstract as well). It makes sense for this to be a const function.
You should implement GetResult in MyInterface, add a Result property in this class and its constructors.
Or you should delete this function in the interface and implement it in a subclass. Because if the interface doesn't hold this property, it may means that the interface knows too much.

Why doesn't my inherited interface use my base class's override?

I have a problem with interfaces and multiple inheritance. I hope to design my program such that one update call processes a variety of objects, with each behavioral 'building block' tucked away in a single function.
For example, I'd like to move a creature from point A to B in one place, regardless of whether it must perform pre/post move actions. But, my multiple inheritance scheme fails (below, with the bug rem'd), making me think I'd need to duplicate code somewhere.
Clearly I don't understand this well enough! (but I'm working hard to learn it)
Q1. Why can't IPhysics::Move 'see' Creature::Move(), in the CreatureAirborne class?
Q2. Am I completely missing the proper usage of interfaces and/or multiple inheritance? If so, any guidance is appreciated!
#include <deque>
#include <memory>
class IGameObject
{
public:
virtual ~IGameObject() {}
virtual void Update() = 0;
};
class IPhysics
{
public:
virtual ~IPhysics() {}
virtual void Move() = 0;
};
class IPhysicsFlight : public IPhysics
{
public:
virtual ~IPhysicsFlight() {}
virtual void Land() = 0;
virtual void TakeOff() = 0;
};
class Creature : public IGameObject, IPhysics
{
protected:
virtual void Move() {}
public:
Creature() {}
virtual ~Creature() {}
virtual void Update() {}
};
class CreatureAirborne : public Creature, IPhysicsFlight
{
private:
virtual void Land() {}
virtual void TakeOff() {}
public:
CreatureAirborne() {}
virtual ~CreatureAirborne() {}
virtual void Update();
};
void CreatureAirborne::Update()
{
TakeOff();
Creature::Move();
Land();
}
int main()
{
std::deque<std::shared_ptr<Creature>> creatures;
std::shared_ptr<Creature> cow(new Creature);
creatures.push_back(cow);
// The butterfly fails to compile with 'cannot instantiate; void IPhysics::Move(void) is abstract'
// std::shared_ptr<CreatureAirborne> butterfly(new CreatureAirborne);
// creatures.push_back(butterfly);
for (auto i : creatures)
{
i->Update();
}
}
It's somewhat had to follow your hierarchy, but it looks correct evaluation on the compiler's part.
You don't have virtual inheritance anywhere, so CreatureAirborne will have duplicated base classes from some point. You will have two instances of IPhysics. Move, that is abstract from there is implemented on the Creature branch but remains abstract on IPhysicsFlight.
You can cure the situation by using virtual inheritance somewhere, or by implementing Move in descendant (say just calling the parent version where it exists).
I would look at things little differently
class CreatureAirborne : public IPhysicsFlight,Creature
While the code runs
new CreatureAirborne ()
The compiler will try to build IPhysicsFlight base class and Creature base class and the fact that IPhysics is a base class to both doesn't play any role rather than confusing.As far as compiler is concerned IPhysicsFlight is abstract and CreatureAirborne did not implement Move
The diamond issue will actually come into play when you do a
(new CreatureAirborne ())->Move()

Restricting method call to another method

There probably is a fairly simple and straight-forward answer for this, but for some reason I can't see it.
I need to restrict calling methods from a class only to some methods implemented by derived classes of some interface.
Say I have
class A{
public:
static void foo();
};
class myInterface{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface{
public:
virtual void onlyCallFooFromHere()
{
A::foo(); //this should work
}
void otherFoo()
{
A::foo(); //i want to get a compilation error here
}
}
So I should be able to call A::foo only from the method onlyCallFooFromHere()
Is there a way to achieve this? I'm open to any suggestions, including changing the class design.
EDIT:
So... I feel there's a need to further explain the issue. I have a utility class which interacts with a database (mainly updates records) - class A.
In my interface (which represents a basic database objects) I have the virtual function updateRecord() from which I call methods from the db utility class. I want to enforce updating the database only in the updateRecord() function of all extending classes and nowhere else. I don't believe this to be a bad design choice, even if not possible. However, if indeed not possible, I would appreciate a different solution.
Change the class design - what you want is impossible.
I am unsure of what you are trying to achieve with so little details and I am unable to comment further.
[Disclaimer: this solution will stop Murphy, not Macchiavelli.]
How about:
class DatabaseQueryInterface {
public:
~virtual DatabseQueryInterface() = 0;
virtual Query compileQuery() const = 0; // or whatever
virtual ResultSet runQuery(const Query&) const = 0; // etc
};
class DatabaseUpdateInterface : public DatabaseQueryInterface {
public:
virtual Update compileUpdate() const = 0; // whatever
};
class DatabaseObject {
public:
virtual ~DatabaseObject() = 0;
protected:
virtual void queryRecord(const DatabaseQueryInterface& interface) = 0;
virtual void updateRecord(const DatabaseUpdateInterface& interface) = 0;
};
class SomeConcreteDatabaseObject : public DatabaseObject {
protected:
virtual void updateRecord(const DatabaseUpdateInterface& interface) {
// gets to use interface->compileUpdate()
}
virtual void queryRecord(const DatabaseQueryInterface& interface) {
// only gets query methods, no updates
}
};
So the basic idea is that your DatabaseObject base class squirrels away a private Query object and a private Update object and when it comes time to call the protected members of the subclass it hands off the Update interface to the updateRecord() method, and the Query interface to the queryRecord() method.
That way the natural thing for the subclasses is to use the object they are passed to talk to the database. Of course they can always resort to dirty tricks to store away a passed-in Update object and try to use it later from a query method, but frankly if they go to such lengths, they're on their own.
You could split your project into different TUs:
// A.h
class A
{
public:
static void foo();
};
// My.h
class myInterface
{
public:
virtual void onlyCallFooFromHere() = 0;
}
class myImplementation : public myInterface
{
public:
virtual void onlyCallFooFromHere();
void otherFoo();
};
// My-with-A.cpp
#include "My.h"
#include "A.h"
void myImplementation::onlyCallFooFromHere() { /* use A */ }
// My-without-A.cpp
#include "My.h"
void myImplementation::otherFoo() { /* no A here */ }
You probably know this, but with inheritance, you can have public, protected, and private member access.
If a member is private in the base class, the derived cannot access it, while if that same member is protected, then the derived class can access it (while it still isn't public, so you're maintaining encapsulation).
There's no way to stop specific functions from being able to see whats available in their scope though (which is what you're asking), but you can design your base class so that the derived classes can only access specific elements of it.
This could be useful because class B could inherit from class A as protected (thus getting its protected members) while class C could inherit from the same class A as public (thus not getting access to its protected members). This will let you get some form of call availability difference at least -- between classes though, not between functions in the same class.
This could work.
class myInterface;
class A {
private:
friend class myInterface;
static void foo();
};
class myInterface {
public:
virtual void onlyCallFooFromHere() {callFoo();}
protected:
void callFoo() {A::foo();}
};
Though at this point I think I'd just make A::foo a static of myInterface. The concerns aren't really separate anymore.
class myInterface {
protected:
static void foo();
};
Is there a reason foo is in A?