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
Related
I have an abstract class like this:
class IMovable {
protected:
MovementPath *movementPath;
public:
IMovable();
virtual ~IMovable();
void setMovementPath(MovementPath *movementPath);
};
Where movementPath is an abstract class on it's own.
When concrete implementation of IMovable is deleted, I need to delete movementPath (more precisely it's concrete implementation at that point) along with any of it's members.
How do I do that?
I tried virtual destructors, but that didn't work (I might have messed something up) and deleting it in concrete implementations crashes the program which it should because it's wrong, blasphemous and should not be done there.
What do I do?
IMovable, as you have shown it, is not an abstract class, as it has no abstract methods of its own. Data members that are pointers to abstract types do not count.
In any case, to answer your question, MovementPath needs a virtual destructor, and then IMovable can call delete movementPath to invoke the correct concrete destructor, regardless of what type it actually is.
For example:
class MovementPath
{
...
public:
virtual ~MovementPath() { ... }
...
};
class IMovable {
protected:
MovementPath *movementPath;
public:
IMovable() : movementPath(0) {}
virtual ~IMovable() { delete movementPath; }
void setMovementPath(MovementPath *newPath) {
// whether or not you need to 'delete movementPath' here
// depends on your particular requirements...
movementPath = newPath;
}
};
class MyMovementPath : public MovementPath
{
...
public:
~MyMovementPath() { ... }
...
};
class MyMovable : public IMovable
{
...
public:
MyMovable() : IMovable() { ... }
~MyMovable() { ... }
...
};
MyMovementPath *path = new MyMovementPath;
MyMovable *movable = new MyMovable;
movable->setMovementPath(path);
...
delete movable; // <-- will delete the path as well...
I got problems formulating it precisely so I left more general description in the title (if you have more precise description of the problem, please comment, I'll edit the title).
The problem: Two classes AudioStream and VideoStream are derived from base class MediaStream which has some common for audio and video stream methods, but is not intended to be used as-is. Consequently, there are two classes AudioStreamSettings and VideoStreamSettings which are derived from MediaStreamSettings and passed to the constructors of their corresponding stream classes. MediaStreamSettings stores settings common for audio and video, and base class MediaStream accesses this data. The question is: what would be the best way to design this hierarchical relationship between base classes of streams and settings?
I can think of a quick solution like the following:
class MediaStream {
public:
MediaStream(const MediaStreamSettings& settings){
// do nothing, let derived classes initialize settings_
// note: I feel guilty for doing this...
}
virtual ~MediaStream(){}
protected:
std::shared_ptr<MediaStreamSettings> settings_;
};
class VideoStream : public MediaStream {
public:
VideoStream(const VideoStreamSettings& settings):
MediaStream(settings)
{
settings_ = std::make_shared<VideoStreamSettings>(settings);
}
void doSomething(){
int s1 = std::dynamic_pointer_cast<VideoStream, MediaStream>(settings_)->getVideoStreamSetting1();
...
}
};
class AudioStream : public MediaStream {
public:
AudioStream(const AudioStreamSettings& settings):
MediaStream(settings)
{
settings_ = std::make_shared<AudioStreamSettings>(settings);
}
}
To summarize I'm not comfortable with two things in this approach:
not initializing settings_ in base class (should I make it abstract to calm myself?)
using dynamic_pointer_cast every time I need to access settings in derived classes (should I make a method wrapper for this?)
One solution is to not store data in MediaStream and add a virtual method
virtual const MediaStreamSettings& GetMediaStreamSettings() const = 0;
Since MediaStream should not be used as-is, making it an abstract class should be acceptable (and desirable).
Thus providing implementation (which includes class members) is pointless.
class IMediaStream {
public:
virtual ~IMediaStream() {}
virtual void play() = 0;
virtual std::shared_ptr<MediaSettings> getSettings() = 0;
private:
IMediaStream() {}
};
template<Setting>
class MediaStream : public IMediaStream {
public:
MediaStream(const Setting& settings){
settings_ = std::make_shared<Setting>(settings);
}
virtual ~MediaStream() {}
virtual void play() override {
// Implementation here
}
virtual std::shared_ptr<MediaSettings> getSettings() override {
return std::dynamic_pointer_cast<Setting, MediaSettings>();
}
private:
std::shared_ptr<Setting> settings_;
}
// Alternatively you can inherit or specialize
// the template to add your implementation
typedef MediaStream<VideoStreamSettings> VideoStream;
typedef MediaStream<AudioStreamSettings> AudioStream;
Let's say I have a parent class, Arbitrary, and two child classes, Foo and Bar. I'm trying to implement a function to insert any Arbitrary object into a database, however, since the child classes contain data specific to those classes, I need to perform slightly different operations depending on the type.
Coming into C++ from Java/C#, my first instinct was to have a function that takes the parent as the parameter use something like instanceof and some if statements to handle child-class-specific behavior.
Pseudocode:
void someClass(Arbitrary obj){
obj.doSomething(); //a member function from the parent class
//more operations based on parent class
if(obj instanceof Foo){
//do Foo specific stuff
}
if(obj instanceof Bar){
//do Bar specific stuff
}
}
However, after looking into how to implement this in C++, the general consensus seemed to be that this is poor design.
If you have to use instanceof, there is, in most cases, something wrong with your design. – mslot
I considered the possibility of overloading the function with each type, but that would seemingly lead to code duplication. And, I would still end up needing to handle the child-specific behavior in the parent class, so that wouldn't solve the problem anyway.
So, my question is, what's the better way of performing operations that where all parent and child classes should be accepted as input, but in which behavior is dictated by the object type?
First, you want to take your Arbitrary by pointer or reference, otherwise you will slice off the derived class. Next, sounds like a case of a virtual method.
void someClass(Arbitrary* obj) {
obj->insertIntoDB();
}
where:
class Arbitrary {
public:
virtual ~Arbitrary();
virtual void insertIntoDB() = 0;
};
So that the subclasses can provide specific overrides:
class Foo : public Arbitrary {
public:
void insertIntoDB() override
// ^^^ if C++11
{
// do Foo-specific insertion here
}
};
Now there might be some common functionality in this insertion between Foo and Bar... so you should put that as a protected method in Arbitrary. protected so that both Foo and Bar have access to it but someClass() doesn't.
In my opinion, if at any place you need to write
if( is_instance_of(Derived1) )
//do something
else if ( is_instance_of(Derived2) )
//do somthing else
...
then it's as sign of bad design. First and most straight forward issue is that of "Maintainence". You have to take care in case further derivation happens. However, sometimes it's necessary. for e.g if your all classes are part of some library. In other cases you should avoid this coding as far as possible.
Most often you can remove the need to check for specific instance by introducing some new classes in the hierarchy. For e.g :-
class BankAccount {};
class SavingAccount : public BankAccount { void creditInterest(); };
class CheckingAccount : public BankAccount { void creditInterest(): };
In this case, there seems to be a need for if/else statement to check for actual object as there is no corresponsing creditInterest() in BanAccount class. However, indroducing a new class could obviate the need for that checking.
class BankAccount {};
class InterestBearingAccount : public BankAccount { void creditInterest(): } {};
class SavingAccount : public InterestBearingAccount { void creditInterest(): };
class CheckingAccount : public InterestBearingAccount { void creditInterest(): };
The issue here is that this will arguably violate SOLID design principles, given that any extension in the number of mapped classes would require new branches in the if statement, otherwise the existing dispatch method will fail (it won't work with any subclass, just those it knows about).
What you are describing looks well suited to inheritance polymorphicism - each of Arbitrary (base), Foo and Bar can take on the concerns of its own fields.
There is likely to be some common database plumbing which can be DRY'd up the base method.
class Arbitrary { // Your base class
protected:
virtual void mapFields(DbCommand& dbCommand) {
// Map the base fields here
}
public:
void saveToDatabase() { // External caller invokes this on any subclass
openConnection();
DbCommand& command = createDbCommand();
mapFields(command); // Polymorphic call
executeDbTransaction(command);
}
}
class Foo : public Arbitrary {
protected: // Hide implementation external parties
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Foo specific fields here
}
}
class Bar : public Arbitrary {
protected:
virtual void mapFields(DbCommand& dbCommand) {
Arbitrary::mapFields();
// Map Bar specific fields here
}
}
If the base class, Arbitrary itself cannot exist in isolation, it should also be marked as abstract.
As StuartLC pointed out, the current design violates the SOLID principles. However, both his answer and Barry's answer has strong coupling with the database, which I do not like (should Arbitrary really need to know about the database?). I would suggest that you make some additional abstraction, and make the database operations independent of the the data types.
One possible implementation may be like:
class Arbitrary {
public:
virtual std::string serialize();
static Arbitrary* deserialize();
};
Your database-related would be like (please notice that the parameter form Arbitrary obj is wrong and can truncate the object):
void someMethod(const Arbitrary& obj)
{
// ...
db.insert(obj.serialize());
}
You can retrieve the string from the database later and deserialize into a suitable object.
So, my question is, what's the better way of performing operations
that where all parent and child classes should be accepted as input,
but in which behavior is dictated by the object type?
You can use Visitor pattern.
#include <iostream>
using namespace std;
class Arbitrary;
class Foo;
class Bar;
class ArbitraryVisitor
{
public:
virtual void visitParent(Arbitrary& m) {};
virtual void visitFoo(Foo& vm) {};
virtual void visitBar(Bar& vm) {};
};
class Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Parent specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitParent(*this);
}
};
class Foo: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Foo specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitFoo(*this);
}
};
class Bar: public Arbitrary
{
public:
virtual void DoSomething()
{
cout<<"do Bar specific stuff"<<endl;
}
virtual void accept(ArbitraryVisitor& v)
{
v.visitBar(*this);
}
};
class SetArbitaryVisitor : public ArbitraryVisitor
{
void visitParent(Arbitrary& vm)
{
vm.DoSomething();
}
void visitFoo(Foo& vm)
{
vm.DoSomething();
}
void visitBar(Bar& vm)
{
vm.DoSomething();
}
};
int main()
{
Arbitrary *arb = new Foo();
SetArbitaryVisitor scv;
arb->accept(scv);
}
I'm sorry the title is so nasty, it's very hard to explain
class BaseState {
protected:
BaseState();
public:
void Some();
void Useful();
void Methods();
};
class UsefulState: public BaseState {
public:
void moreUsefulStuff();
};
class SomeUsefulBase {
protected:
SomeUsefulBase(BaseState* pState) { state = pState; }
void UsefulMethods() { state->Some(); }
void Andthings() { state->Useful(); }
public:
virtual void doSomething() = 0;
protected:
BaseState* state;
};
class SomethingUseful: public SomeUsefulBase {
public:
SomethingUseful(UsefulState* pState): SomeUsefulBase(pState) {
usefulState = pState;
}
virtual void doSomething() { usefulState->moreUsefulStuff();}
protected:
UsefulState* usefulState;
};
then:
SomethingUseful whatever(new UsefulState());
It's not important where things are allocated but there will be a lot of classes derived from SomethingUseful that will use a UsefulState however, all the member functions of SomeUsefulBase will use the state, but as a BaseState
I am hoping there is a better way than using two members (UsefulState and BaseState pointers in the definitions), I've thought of a union and a template, but that would be ugly.
I also don't want to litter my code with casts, I'm wondering if there is a nicer notation.
There will be one UsefulState per operation, and a large tree structure will be formed of various subclasses of SomethingUseful and/or subclasses of SomethingUsefulBase where a UsefulState pointer is expected.
Addendum:
Not sure what's up with SO's syntax highlighting! It seems to be using case to decide if it wants to colour things blue or not.... not sure how that works.
Addendum 2:
In the use this example is derived from there is one state per operation but many things derived from SomeUsefulBase, the derived classes will create each other to form a large tree structure (god I sound noobish) but will all require the use of the derived state.
That sounds like the standard "abstract factory"-type situation:
struct AbstractGadget { virtual ~AbstractGadget() {} };
struct AbstractWidget { virtual ~AbstractWidget() {} };
struct AbstractThingy { virtual ~AbstractThingy() {} };
struct AbstractFactory
{
virtual ~AbstractFactory() {}
virtual std::unique_ptr<AbstractGadget> make_gadget() = 0;
virtual std::unique_ptr<AbstractGadget> make_widget() = 0;
virtual std::unique_ptr<AbstractGadget> make_thingy() = 0;
};
Usage:
struct Gadget1 : AbstractGadget { /* ... */ };
struct Widget1 : AbstractWidget { /* ... */ };
struct Thingy1 : AbstractThingy { /* ... */ };
struct Factory1 : AbstractFactory
{
virtual std::unique_ptr<AbstractGadget> make_gadget()
{
return { new Gadget1; }
}
// ...
};
And so forth for Factory2 and Widget3 etc. There's plenty of potential for eliminating boilerplate code with templates here, too.
Consumers might be given an AbstractFactory & f and call f.make_gadget() etc. to create objects of a suitable type.
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.