For example, say I have a basic data object class as below.
class DataObject {
protected:
bool data_changed;
virtual void save() {}
virtual void load() {}
public:
virtual void idle() {
if (data_changed) {
save();
data_changed = false;
}
}
};
The idea is that "idle" is called periodically from some main looping thread and performs non-critical updates.
Now I want derived classes to be able to have their own idle functions. But I don't want to lose the default behavior.
One solution is to say "remember to call DataObject::idle() from overridden idle() functions".
Like this:
class ChildData : public DataObject {
public:
virtual void idle() override {
//do something
DataObject::idle(); //remember to call parent idle!
}
};
But this is very dangerous as people can just forget.
Is there a way to enforce this somehow? Or make it automatic, like a virtual destructor?
(My current "workaround" is to have 2 functions, one the parent_idle that does the important stuff, and then one overridable child_idle that derived functions can override. But this is a bit messy, and also you have to make a whole new set of functions again if you want some child function to enforce its own default...)
Maybe you could write it:
...
void idle_start() { // not virtual, main looping thread calls this
idle();
if (data_changed) {
save();
data_changed = false;
}
}
virtual void idle() { } // virtual, noop by default
...
That depends if you want to have your derived behavior before the mandatory base behavior.
Related
In Java you can create an object whilst at the same time providing (or overloading) abstract functions within the object, thus:
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Whatever in here
}
};
I really like that way of doing it, and was wondering if there was some similar construct in C++.
Basically I want a base class with a couple of PV functions declared in it (amongst other stuff), and the user to create an instance of that class whilst at the same time providing the body of the PV functions.
I know I could create child classes, but that seems a little clunky for what I need, where each child class would be unique and only be used to make one instance each.
I have thought about providing lamdas to the constructor and using those instead of actual member functions, but that really seems messy and hard for a novice user to get their head around - not to mention that it would be too rigid (I'd also like to be able to override some non-pure virtual functions optionally).
So is child classes the only way to go, or is there some lesser-known construct in some newer C++ standard that I don't know about that could do what I want?
To expand a little - the idea is to have a class like:
class Thread {
// other stuff
public:
virtual void setup() = 0;
virtual void loop() = 0;
// other functions, some virtual but not pure
};
Thread threadOne {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Thread threadTwo {
void setup() {
// Init code for this thread
}
void loop() {
// Run code for this thread
}
};
Obviously not that syntax, but it gives you an idea of how I'd like to use the class.
It's intended to be run on an embedded system with a slimmed-down C++ implementation (it's g++ but without the full STL). End users aren't the brightest bunch, so it has to be kept as simple to understand as possible.
Anonymous child classes are the closest to what I'd like (though still not perfect). I can use CPP macros to help abstract some of the class implementation syntactic sugar which would help.
Here's a compilable construct I have come up with. Is there anything "wrong" with this approach given the constraints above?
#define THREAD(NAME, CONTENT) class : public Thread {\
public:\
CONTENT\
} NAME;
class Thread {
private:
uint32_t stack[256]; // 1kB stack
volatile bool _running;
public:
virtual void setup() = 0;
virtual void loop() = 0;
void start();
void stop();
uint8_t state();
static void spawn(Thread *thr);
void threadRunner();
};
void Thread::spawn(Thread *thread) {
thread->threadRunner();
}
void Thread::start() {
Thread::spawn(this);
}
void Thread::threadRunner() {
_running = true;
setup();
while (_running) {
loop();
}
}
void Thread::stop() {
_running = false;
}
uint8_t Thread::state() {
return 0;
}
THREAD(myThread,
void setup() override {
}
void loop() override {
}
)
void setup() {
myThread.start();
}
void loop() {
}
Obviously it doesn't actually do anything yet - the whole of the threading back-end is a separate issue, and will be ported over from some existing code I wrote a few years back. I am mainly interested in simplifying the interface for the end user.
There is multiple possibilities, but I'd stick with something simple and versatile: callbacks and lambdas instead of virtual function and inheritance.
class ActionListener
{
std::function<void(int)> _action_performed;
public:
template<class CB>
ActionListener(CB cb) : _action_performed(cb) {}
void click() { _action_performed(0); }
};
int main()
{
ActionListener al([](int n) { std::cout << "Action Performed #" << n << "\n"; });
al.click(); // prints "Action Performed #0"
}
live demo
I'd also like to be able to override some non-pure virtual functions optionally
Which, semantically speaking, means providing a default behavior. This is possible:
ActionListener(CB cb) : _action_performed(cb) {} // construct an AL with the given callback
ActionListener() : _action_performed(default_action_performed) {} // construct an AL with a default callback
void default_action_performed(int n) { /*...*/ }
well, as you already mentioned, one way would be child classes.
another way would be providing some std::functions (or lambdas), either in the constructor or have some set functions.
store the function as a member and call this once your "virtual" member function is called: If you want it optional:
class MyBase
{
public:
MyBase();
void SetFunc(const std::function<int()>& myFun)
{
m_myFun = myFun;
}
int MyVirtFunc()
{
if(m_myFun)
{
return m_myFun();
}
else
{
return 42;
}
}
private:
std::function<int()> m_myFun;
}
if you want the functions given mandatory, put them in the constructor:
class MyBase
{
public:
MyBase(const std::function<int()>& myFun)
: m_myFun(myFun) {}
int MyVirtFun() { return m_myFun(); }
private:
const std::function<int()> m_myFun;
}
Having the Observer pattern.
class Observer
{
virtual eventA()=0;
virtual eventB()=0;
...
virtual eventZ()=0;
}
The Observer class cannot be changed, but my class is only interested in the event B. Therefore I need to:
class MyObserver{
eventA() override {}
eventB() override { /* Do something */ }
eventC() override {}
...
eventZ() override {}
}
It is overhead to empty-implement all events, specially if you have a policy to always implement in cpp files (except templates obviously).
Does C++11 offer any keyword for that? Like
...
eventC() override = empty;
...
In that way, I wouldn't need to add the empty implementation in the CPP file.
What you are looking for doesn't exist.
Anyway, you can do this:
struct Observer {
virtual ~Observer() = 0;
virtual void eventA() {}
virtual void eventB() {}
// ...
virtual void eventZ() {}
};
Observer::~Observer() { }
struct MyObserver: Observer {
void eventB() override { /* Do something */ }
};
Here you have:
Observer still abstract (thanks to its destructor), so you cannot instantiate objects of this type
A default empty implementation for all of your methods
No need to define empty bodies in your derived classes for those methods in which you are not interested
Thus, as a consequence:
int main() {
// This compiles and works as expected
Observer *O = new MyObserver;
// The following line doesn't compile
// Observer *O = new Observer;
}
Ok, but you said that:
The Observer class cannot be changed
In this case, you can define an intermediate class that is not instantiable from which to derive, as an example:
struct IntermediateObserver: Observer {
virtual ~IntermediateObserver() = 0;
void eventA() override {}
void eventB() override {}
// ...
void eventZ() override {}
};
IntermediateObserver::~IntermediateObserver() { }
struct MyObserver: IntermediateObserver {
void eventB() override { /* Do something */ }
};
From now on, derive all your custom observers from IntermediateObserver and that's all.
Your design violates the Interface segregation principle, stating that no client should be forced to depend on methods it does not use/need.
Maybe you should reconsider the design and create several Observer base classes, one for each event?
If you can not change the design, use {}, there is no empty, default or delete for user-written functions.
Does C++11 offer any keyword for that?
No
I'm having problems wording this question concisely, but basically there is a function in a class that may be the last class in an inheritance chain, or it may not be. Inside this function, IF the class-level function is the last in an inheritance chain, a 2nd function will be called. It is much easier to show what I'm talking about than to explain it, so:
Lets say that I have class Z.
Z derives from Y, which derives from X, which derives from W.
All of the classes have a virtual function called Execute().
Z.Execute() requires that Y.Execute() be finished, which requires that X.Execute() be finished, which requires that W.Execute() be finished.
As such, Z's Execute() function looks like:
void Z::Execute(void)
{
Y::Execute();
// do Z's stuff!
return;
}
Similarly, Y's Execute() function looks like:
void Y::Execute(void)
{
X::Execute();
// do Y's stuff!
return;
}
And so on down the chain of inheritance.
But Y, nor X, nor W are abstract, and so each can be instantiated, and may or may not be the last class in the inheritance chain.
Here's what I need to know. The last Execute() needs to call DoThisAtEndOfExecute(). DoThisAtEndOfExecute() needs to be called internal to the classes, ie. it will not be public.
So it can't be in X's Execute(), because if the class is a Y, it'll be called too early. It can't be in Y's Execute(), because the class may be a Z. It can't be in Z's Execute() because if the class is an Y, X, or W, the function will never get called.
So is there any way for a class to tell whether it has been inherited FROM? Basically, the equivalent to:
if (!IAmTheParentOfSomething)
DoThisAtEndOfExecute();
How is this ever done? I concede that an easier way would be for the function that contains the class to do:
X.Execute();
X.DoThisAtEndOfExecute();
But that isn't really an option for this code.
I think what you want can be achieved if you split Execute into a nonvirtual part and a virtual part. The former will run the latter, then invoke DoThisAtEndOfExecute. Like this:
class X
{
public:
void Execute()
{
ExecuteImpl(); //That one's virtual, the derived classes override it
DoThisAtEndOfExecute();
}
protected:
virtual void ExecuteImpl()
{
//Whatever was in the legacy Execute
}
}
Y and Z override ExecuteImpl() and call the base. This way, DoThisAtEndOfExecute() runs after the most derived version of ExecuteImpl() is finished, without any knowledge of the actual class.
One possible solution is to add a default parameter to Execute, and in subsequent calls change that parameter to some other value.
class X{
void Execute(bool isFinal = true);
};
//and so on.
void Z::Execute(bool isFinal)
{
Y::Execute(false);
// do Z's stuff!
if(isFinal){
// You're up!
}
return;
}
void Y::Execute(bool isFinal)
{
X::Execute(false);
// do Y's stuff!
if(isFinal){
// Y is the last class in this chain.
}
return;
}
This way, whenever code calls an object's Execute method (without a parameter), then the method will be told that some outside code is executing it. This also allows you to prevent said termination code from being executed if you so choose, by passing false to the method.
How about moving the // do ...'s stuff! into a seperate function?
class W
{
protected:
void Stuff() { /*...*/ };
void Finalize() { /*...*/ };
public:
virtual ~W() {}
virtual void Execute() { /*...*/ };
};
class X : public W
{
protected:
void Stuff() {
// X Stuff
W::Stuff();
};
public:
virtual ~X() {}
virtual void Execute() {
X::Stuff();
W::Finalize();
};
};
class Y : public X
{
void Stuff() {
// Y Stuff
X::Stuff();
};
public:
virtual ~Y() {}
virtual void Execute() {
Y::Stuff();
W::Finalize();
};
};
I have a problem, and I tried to use RTTI to resolve it.
I have a class Base and children classes (in the example, I show only one Child)
class Base {
virtual void Eval() {
// normal treatment
+
// treatment only for Base instance
}
};
class Child : Base {
void Eval() {
// call Base Eval
Base::Eval();
//other treatment
}
};
The problem, is that in Base::Eval, there are some treatments which I dont't want to execute when I call it from Child.
What I mean, in Child::Eval, when we call the Base::Eval, we want only the normal treatment which is executed.
For this, I thought about RTTI. I don't know if it is the best way to use it, I thought to do something like this:
class Base {
virtual void Eval() {
// normal treatment
+
if (typeid(this).name() == typeid(Base).name()) {
// treatment only for Base instance
}
}
}
The question is: Is it permitted to do that?
Am I obliged to check typeid.name()?
Or would just typeid() be enough?
Situations such as this are almost always an indication of bad design. A base class should not know anything about its derived classes.
If you want to give derived classes an option to customise parts of the base behaviour, use virtual functions and the "template method" design pattern:
class Base
{
public:
virtual void Eval() {
// normal treatment
Eval_CustomisationHook();
}
protected:
virtual void Eval_CustomisationHook()
{
// Do the stuff
}
};
class Child : public Base
{
protected:
virtual void Eval_CustomisationHook()
{} // do nothing
};
Alternatively, you could delegate just the query:
class Base
{
public:
virtual void Eval() {
// normal treatment
if (doOptionalEvalPart()) {
// do it here
}
}
protected:
virtual bool doOptionalEvalPart()
{
return true;
}
};
class Child : public Base
{
protected:
virtual bool doOptionalEvalPart()
{
return false;
}
};
And to answer your original question as well: the correct form would be to compare the std::type_info objects, not their names. And don't forget you'd have to dereference this. So the code would look like this:
if (typeid(*this) == typeid(Base))
This will do what you want it to. But as I've said above, this is most probably not the proper approach.
CLOS has a neat concept of :before, :after, and :around methods.
The :before methods are called before the primary method.
The :after methods are called after the primary method.
The :around methods are called around the :before+primary+:after sequence.
The :before, :after, and :around methods are chained rather than overridden. Suppose both a parent and child class define a foo method and :before foo method. The child's foo method overrides the parent's foo method, but both the child's and parent's :before foo methods are called before this overridden method is called.
Python decorators provide something similar to the CLOS :around methods. There is nothing like this in C++. It has to be hand-rolled:
class Child : public Parent {
virtual void do_something (Elided arguments) {
do_some_preliminary_stuff();
Parent::do_something (arguments);
do_some_followup_stuff();
}
};
Downsides:
This is an anti-pattern to some people.
It requires me to be explicit in specifying the parent class.
It requires extenders of my classes to follow the same paradigm.
What if I need to call the grandparent because the parent doesn't override do_something, and what about multiple inheritance?
It doesn't quite capture the CLOS concept.
I found these concepts to be quite handy way back when I used Flavors (predecessor to CLOS). I've used the above workaround in a few places, and a few have challenged it as an anti-pattern. (Others have emulated it elsewhere, so the derision is not universal.)
The question: Is this considered an anti-pattern in C++, and are there better workarounds?
You can get the basics of this quite nicely using (std/boost)::shared_ptr. For details see here : http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/sp_techniques.html#wrapper
Getting the inheritance behaviour you mention just requires the prefix/suffix functions to call the prefix/suffix functions in the parent class.
This is what I could do, but it's still a bit ugly.
Basically I put the actual work in a separate hook so you don't have call the pre/post hooks in the processing method. In the inheritance chain you have total control both on whether you want to add pre/post hooks and the ordering of the hook calls (call the parent's hook before or after the child's hook).
#include <iostream>
#define C(s) std::cout << s << std::endl;
class Parent {
public:
virtual void do_something(int arg) {
do_some_pre_hook();
do_some_hook(arg);
do_some_post_hook();
}
virtual void do_some_pre_hook() {
C("parent pre_hook");
}
virtual void do_some_post_hook() {
C("parent post_hook");
}
virtual void do_some_hook(int arg) {
//this is where you actually do the work
}
};
class Child : public Parent {
public:
typedef Parent super;
virtual void do_some_pre_hook() {
super::do_some_pre_hook();
C("Child pre_hook");
}
virtual void do_some_post_hook() {
super::do_some_post_hook();
C("Child post_hook");
}
};
class GrandChild : public Child {
public:
typedef Child super;
virtual void do_some_pre_hook() {
super::do_some_pre_hook();
C("GrandChild pre_hook");
}
virtual void do_some_post_hook() {
super::do_some_post_hook();
C("GrandChild post_hook");
}
virtual void do_some_hook(int arg) {
//this is where you actually do the work
C("GrandChild hook");
}
};
int main() {
GrandChild gc;
gc.do_something(12);
}
Note: Ideally you would use an AOP c++ compiler or compiler extension for a task like that, but the last time I tried it it wasn't quite stable...
I'm not claiming this is equivalent or comparable to what other languages do, but I think the Non Virtual Interface idiom is applicable for your problem:
class parent {
public:
void foo()
{
before_foo();
do_foo();
after_foo();
}
protected:
// you can make those pure virtual with an implentation, too
virtual void before_foo() { ... }
virtual void do_foo() { ... }
virtual void after_foo() { ... }
};
class child: public parent {
protected: // or private
void before_foo() { ... }
void do_foo() { ... }
// must provide a dummy after_foo that delegates to parent::after_foo
// if it is pure virtual in the parent class
};
When calling p.foo(), the most derived before_foo, after_foo and do_foo are always called.