This question already has answers here:
Inherit interfaces which share a method name
(5 answers)
Closed 5 years ago.
I have the following code using multiple inheritance. The purpose is to use two interfaces as one in the derived class:
struct InterfaceA
{
virtual void register_stuff();
virtual void on_state_changed( const State state ) = 0;
};
struct InterfaceB
{
virtual void register_stuff();
virtual void on_state_changed( const State state ) = 0;
};
struct Derived : InterfaceA, InterfaceB
{
void register_stuff() override
{
InterfaceA::register_stuff();
InterfaceB::register_stuff();
}
void on_state_changed( const State state ) override
{
// how can I know who is responding?
}
};
Registering the interfaces will cause an asynchronous call to on_state_changed. Is it possible to discern which interface is calling it?
You'll have to add a layer in-between to disambiguate. Here's a small utility that creates those on the fly:
template<class Inteface>
struct disambiguate : Interface {
void on_state_changed( const State state ) override final {
on_state_changed(state, this);
}
virtual void on_state_changed( const State &state, disambiguate* ) = 0;
};
And that's it. Then it's a matter of defining your class in terms of this utility:
struct Derived : disambiguate<InterfaceA>, disambiguate<InterfaceB>
{
void register_stuff() override
{
InterfaceA::register_stuff();
InterfaceB::register_stuff();
}
void on_state_changed( const State &state, disambiguate<InterfaceA>* ) override
{
// Called for A
}
void on_state_changed( const State &state, disambiguate<InterfaceB>* ) override
{
// Called for B
}
};
I've used another parameter and overloading to make this templatized, but the technique itself can also be done by writing the classes out and calling a virtual function with a new name. The key is to make the original virtual call (via the interface pointer) reach a short thunk that calls the disambiguated function.
Alternatively it is possible to provide separate implementations for handlers directly in the code of Derived:
struct Derived : InterfaceA, InterfaceB
{
void register_stuff() override
{
InterfaceA::register_stuff();
InterfaceB::register_stuff();
}
void InterfaceA::on_state_changed( const State state ) override
{
// responding A
}
void InterfaceB::on_state_changed( const State state ) override
{
// responding B
}
};
EDIT: Unfortunately this solution is nonstandard and supported only by Visual C++ compilers.
I was thinking about using templates for disambiguating too, but I belive #StoryTeller 's answer is more elegant.
struct InterfaceA
{
virtual void register_stuff(); // calls on_state_changed<InterfaceA>()
template <typename Interface>
virtual void on_state_changed( const State state ) = 0;
};
struct InterfaceB
{
virtual void register_stuff(); // calls on_state_changed<InterfaceB>()
template <typename Interface>
virtual void on_state_changed( const State state ) = 0;
};
struct Derived : InterfaceA, InterfaceB
{
void register_stuff() override
{
InterfaceA::register_stuff();
InterfaceB::register_stuff();
}
template <typename Interface>
void on_state_changed( const State state ) override
{
// how can I know who is responding?
// : "Interface" is responding
}
};
Related
This question already has answers here:
Can I call a base class's virtual function if I'm overriding it?
(8 answers)
Closed last year.
I'm struggling to find the right answer on below question on the internet.
I'm not a native C++ programmer and have more knowledge of OOP programming in PHP, Pascal, and JavaScript, but i can manage.
I want to create a class hierarchy to handle some tasks like displaying content on a LCD screen.
It looks like the following classes:
class base {
public:
base() { };
virtual void display() { // Need to be called first from all child objects };
virtual bool keyPress(int state) { //Need to be called first from all child objects };
};
class child : public base {
public:
child():base() {};
virtual void display() {
>> call base->display()
// do some stuff
};
virtual bool keyPress(int state) {
>> call base->keyPress(state)
// check some stuff
};
};
Most program language that i know of has some 'parent::' solution to call the inherited virtual method but i cant find anything comparable for C++.
an option that i going to use for now is:
class base {
protected:
virtual void _display() =0;
virtual bool _keyPress(int state) =0;
public:
base() { };
void display() {
// do basic stuff
_display();
};
bool keyPress(int state) {
if (!_keyPress(state)) {
// do basic stuff.
};
};
class child : public base {
protected:
virtual void _display() {
// do some stuff
};
virtual bool _keyPress(int state) {
// check some stuff
};
public:
child():base() {};
};
I do not like this method but it will work.
The right syntax is base::display():
class base {
public:
base() { };
virtual void display() { /* Need to be called first from all child objects*/ };
virtual bool keyPress(int state) { /*Need to be called first from all child objects*/ return 42; };
};
class child : public base {
public:
child():base() {};
virtual void display() {
base::display();
// do some stuff
};
virtual bool keyPress(int state) {
return base::keyPress(state);
// check some stuff
};
};
However, if it is the same in all child classes you better let base call its methods like you do it in your second code. It is not clear why you "do not like this method". It works, does what you want, and avoids lots of duplicate code and decreases chances for mistakes in the derived classes. Just note that the virtual methods need not be protected, because the derived classes are not supposed to call them directly, you can make them private: https://godbolt.org/z/1qjooKq85 (perhaps that is what you didn't like?).
The content
The question
Example
Why do I need it
Hi.
The question
I am facing a problem. I have a class A that has a base B (is polymorphic). In B class is method Print(), wich is virtual. In A class is also Print(). virtual.
Lets say I am given an A type object (or pointer), stored in B variable
B * object = new A();
And by calling
object->Print();
It calls the method in A class, but I also want it to call method in B class.
Technically
I want to call the method for each child until i reach class that has no child
This can be done as follows:
Example
class A
{
public:
virtual void Print() const override
{
cout << "A" << endl;
}
};
class B : public A
{
public:
virtual void Print() const override
{
cout << "B" << endl;
A::Print(); // i do not want to call it here...
}
};
The problem is that I do want not to be forced to call the
A::Print();
Why
Yes, you might be asking, what is the deal...
I have very long inheritance chain. (lets say that there are like 15 - 20 classes in the inheritance chain).
In a game, each one does some little thing.
Lets say
class GameObject
{
public:
virtual void Update() const
{
//updates position, recounts it towards screen
}
};
class Character : public GameObject
{
public:
virtual void Update() const override
{
// Updates lives, movement
}
};
class Warrior : public Character
{
public:
virtual void Update() const override
{
// Updates armor, specific stuff
}
};
Now this example is very simplified. Problem is, that if i forget to add a call base::Update() Then I am worndering why does it not work. Looking for such a misstake is hard. I mean, if there any way around it?
Thank you very much indeed for any responses.
Have a nice day
If indeed every class must call the base function, one way to ensure the functionality is enforced is to use the template pattern.
class GameObject
{
public:
void Updater()
{
Update(); // this is a virtual call
GameObject::Update(); // now call base
}
virtual void Update() const
{
}
};
class Character : public GameObject
{
public:
virtual void Update() const override
{
// Updates lives, movement
}
};
class Warrior : public Character
{
public:
virtual void Update() const override
{
// Updates armor, specific stuff
}
};
class Character : public GameObject
{
public:
virtual void Update() const override
{
// Updates lives, movement
}
};
class Warrior : public Character
{
public:
virtual void Update() const override
{
// Updates armor, specific stuff
}
};
Then always call YourObject::Updater(); instead of YourObject::Update(). The Updater function will call your object's Update function, and then return and call the base class Update.
There was once a proposal to get all the bases of a given type (N2965) which gcc actually implemented in <tr2/type_traits>. So, if portability is not a concern and you happen to be using gcc, you can write a catch-all like so:
struct A {
virtual ~A() = default;
virtual void print() { print_all(*this); }
void print_one() { std::cout << "A\n"; }
protected:
template <class T>
void print_all(T& object) {
object.print_one();
print_all(object, typename std::tr2::bases<T>::type{});
}
template <class T, class... Bases>
void print_all(T& object, std::tr2::__reflection_typelist<Bases...> ) {
using swallow = int[];
(void)swallow{0,
(static_cast<Bases&>(object).print_one(), 0)...
};
}
};
This splits up print(), which prints everything, and print_one() which just prints the one specific type. You just have your print() call print_all() with itself:
struct B : A {
void print() override { print_all(*this); }
void print_one() { std::cout << "B\n"; }
};
struct C : B {
void print() override { print_all(*this); }
void print_one() { std::cout << "C\n"; }
};
Otherwise, you'll have to wait for one of the reflection proposals to get adopted.
I am looking for an elegant solution for my case. I tried to find a design pattern that specified and offers solution for this case but i failed to find one.
I have a base class that uses to store general object and later Invoke it.
I want the execution will be separated into two parts:
A must have part which will always take place (do1st()).
User defined code (do2nd()).
For example:
class InvokeBase
{
public:
InvokeBase(void *ptr) : context_(ptr) {}
virtual ~InvokeBase () {}
void operator()() = 0;
protected:
void do1st() {//Mandatory code to execute for every InvokeBase type when calling operator()};
void * context_;
};
class InvokeDerived : public InvokeBase
{
public:
InvokeDerived(void *ptr) : base(ptr){}
virtual ~InvokeDerived();
void do2nd() {//User defined code}
void operator()()
{
do1st(); // << How to force this execution?
do2nd();
}
};
void main()
{
InvokeBase *t = new InvokeDerived();
t(); // << here i want the execution order will be do1st and then do2nd.
}
The trick is that i want do1st will execute always, that i will not have to call it from InvokeDerived. I want to allow the user to inherit from InvokeBase with the guarantee that do1st will always be called when invoking the operator().
This is the template method pattern: split a function with semi-flexible behavior accross the class hierarchy into multiple parts, and make virtual only the ones that change:
class InvokeBase
{
public:
InvokeBase(void *ptr) : context_(ptr) {}
virtual ~InvokeBase () {}
void operator()() // this is non-virtual (this is the template method)
{
do1st();
do2nd(); // this resolves to virtual call
}
protected:
void do1st() { /* fixed code here */ };
virtual void do2nd() = 0; // variable part here
void * context_;
};
class InvokeDerived : public InvokeBase
{
public:
InvokeDerived(void *ptr) : base(ptr){}
virtual ~InvokeDerived() = default;
protected:
void do2nd() override
{
// code speciffic to InvokeDerived here
}
};
My classes are
Base
Derived_A
Derived_B
Parent
Child_One
Child_Two
Base has two signature functions:
virtual void foo( const Parent& ) = 0;
virtual void bar( const Base& ) = 0;
, which other parts of the program expect.
The problem is:
Derived_A treats Child_One and Child_Two the same. But Derived_B treats them differently.
How should I implement this?
One way is to find out what kind of object is passed to Derived_B.foo. This would be apparently "a design flaw".
The other way I tried is to change the signature functions as:
class Base
{
class Derived_A;
class Derived_B;
// virtual void bar( const Base& ) = 0;
virtual void bar( const Derived_A& ) = 0;
virtual void bar( const Derived_B& ) = 0;
}
class Derived_A: public virtual Base
{
virtual void foo( const Parent& ) = 0;
}
class Derived_B: public virtual Base
{
virtual void foo( const Child_A& ) = 0;
virtual void foo( const Child_B& ) = 0;
}
But now the bar function cannot use Base.foo. So I have to write the bar function twice, although the code is exactly the same.
Are there any other ways to deal with the problem? which one do you suggest?
P.S. I couldn't think of a good title. Please feel free to modify it.
The problem you are describing is called Double Dispatch. The link describes the problem and a few possible approaches to a solution (including polymorphic function signatures and the visitor pattern).
Without details of what the two type hierarchies' relation is with each other and how they interact, it's impossible to say what approach is appropriate. I've composed an overview of the other answers and another viable alternative that can be extended to the visitor pattern which was mentioned in a comment.
Performing the polymorphic behaviour in the children implementing a virtual function in Parent as already suggested by Joey Andres is quite typical object oriented solution for this problem in general. Whether it's appropriate, depends on the responsibilities of the objects.
The type detection as suggested by Olayinka and already mentioned in your question certainly smells kludgy, but depending on details, can be the minimum of N evils. It can be implemented with member function returning an enum (I guess that's what Olayinka's answer tries to represent) or with a series of dynamic_casts as shown in one of the answers in the question you linked.
A trivial solution could be to overload foo in Base:
struct Base {
virtual void foo(const Parent&) = 0;
virtual void foo(const Child_Two&) = 0;
};
struct Derived_A: Base {
void foo(const Parent& p) {
// treat same
}
void foo(const Child_Two& p) {
foo(static_cast<Parent&>(p));
}
};
struct Derived_A: Base {
void foo(const Parent& p) {
// treat Child_One (and other)
}
void foo(const Child_Two& p) {
// treat Child_Two
}
};
If there are other subtypes of Base that treat Child_One and Child_Two the same, then the implementation of foo(const Child_Two&) may be put in Base to avoid duplication.
The catch of this approach is that foo must be called with a reference of proper static type. The call will not resolve based on the dynamic type. That may be better or worse for your design. If you need polymorphic behaviour, you can use the visitor pattern which essentially adds virtual dispatch on top of the solution above:
struct Base {
foo(Parent& p) {
p.accept(*this);
}
virtual void visit(Child_A&) = 0;
virtual void visit(Child_B&) = 0;
};
struct Parent {
virtual void accept(Base&) = 0;
};
struct Child_A: Parent {
void accept(Base& v) {
v.visit(*this);
}
};
// Child_B similarly
struct Derived_A: Base {
void treat_same(Parent&) {
// ...
}
void visit(Child_A& a) {
treat_same(a);
}
void visit(Child_B& b) {
treat_same(b);
}
};
struct Derived_B: Base {
void visit(Child_A&) {
// ...
}
void visit(Child_B&) {
// ...
}
};
There's a bit more boilerplate, but since you seem very averse to implementing the behaviour in the children, this may be good approach for you.
You could've easily made a virtual foo method in Parent. Since you want Derive_A to treat all Parent's subclasses the same, why not implement a class that does just that in Parent. That is the most logical thing, since chances are, if you want to do the same to both of them, then both of them must have similar data, which is exist in Parent.
class Parent{
virtual void treatSame(){
// Some operations that treat both Child_A, and Child_B
// the same thing to both Child_A and Child_B.
}
virtual void foo() = 0;
}
Since you want Derived_B to do different operations in both Child_A and Child_B, take advantage of polymorphism. Consider the rest of the classes below:
class Child_A : public Parent{
virtual void foo(){
// Foo that is designed for special Child_A.
}
}
class Child_B : public Parent{
virtual void foo(){
// Foo that is designed for special Child_B.
}
}
class Base{
virtual void foo(Parent) = 0;
virtual void bar(Base) = 0;
}
class Derived_A: public Base
{
virtual void foo( Parent& p){
p.treatSame();
}
}
class Derived_B: public Base
{
virtual void foo( Parent& p){
p.foo(); // Calls appropriate function, thanks to polymorphism.
}
}
A possible usage is the following:
int main(){
Child_A a;
Child_B b;
Derived_A da;
da.foo(a); // Calls a.treatSame();
da.foo(b); // Calls a.treatSame();
Derived_B db;
db.foo(a); // Calls a.foo();
db.foo(b); // Calls b.foo();
}
Note that this will only work when the parameters are pointer or reference (I prefer to deal with reference when possible). Virtual dispatch (selecting appropriate function) won't work otherwise.
I'm not sure of the syntax but you get the gist.
class Base{
virtual void bar( Base ) = 0;
virtual void foo( Parent ) = 0;
}
class Derived_A: public virtual Base{
virtual void foo( Parent ) = 0;
}
class Derived_B: public virtual Base{
virtual void foo( Parent ){
//switch case also works
return parent.get_type() == Parent::TYPE_A ? foo_A((Child_A)parent) : foo_B((Child_B)parent);
}
virtual void foo_A( Child_A ) = 0;
virtual void foo_B( Child_B ) = 0;
}
class Parent{
virtual int get_type() = 0;
}
class Child_A: public virtual Parent{
return Parent::TYPE_A;
}
class Child_B: public virtual Parent{
return Parent::TYPE_B;
}
I'm working on a plugin framework, which supports multiple variants of a base plugin class CPlugin : IPlugin. I am using a boost::shared_ptr<IPlugin> for all reference to the plugins, except when a subsystem needs the plugin type's specific interface. I also need the ability to clone a plugin into another seprate object. This must return a PluginPtr. This is why CPlugin is a template rather than a straight class. CPlugin::Clone() is where the template paramter is used. The following are the class definitions I am using:
IPlugin.h
#include "PluginMgr.h"
class IPlugin;
typedef boost::shared_ptr<IPlugin> PluginPtr;
class IPlugin
{
public:
virtual PluginPtr Clone() =0;
virtual TYPE Type() const =0;
virtual CStdString Uuid() const =0;
virtual CStdString Parent() const =0;
virtual CStdString Name() const =0;
virtual bool Disabled() const =0;
private:
friend class CPluginMgr;
virtual void Enable() =0;
virtual void Disable() =0;
};
CPlugin.h
#include "IPlugin.h"
template<typename Derived>
class CPlugin : public IPlugin
{
public:
CPlugin(const PluginProps &props);
CPlugin(const CPlugin&);
virtual ~CPlugin();
PluginPtr Clone();
TYPE Type() const { return m_type; }
CStdString Uuid() const { return m_uuid; }
CStdString Parent() const { return m_guid_parent; }
CStdString Name() const { return m_strName; }
bool Disabled() const { return m_disabled; }
private:
void Enable() { m_disabled = false; }
void Disable() { m_disabled = true; }
TYPE m_type;
CStdString m_uuid;
CStdString m_uuid_parent;
bool m_disabled;
};
template<typename Derived>
PluginPtr CPlugin<Derived>::Clone()
{
PluginPtr plugin(new Derived(dynamic_cast<Derived&>(*this)));
return plugin;
}
An example concrete class CAudioDSP.h
#include "Plugin.h"
class CAudioDSP : CPlugin<CAudioDSP>
{
CAudioDSP(const PluginProps &props);
bool DoSomethingTypeSpecific();
<..snip..>
};
My problem (finally) is that CPluginMgr needs to update m_disabled of the concrete class, however as it is passed a PluginPtr it has no way to determine the type and behave differently according to the template paramater. I can't see how to avoid declaring ::Enable() and ::Disable() as private members of IPlugin instead but this instantly means that every section of the application now needs to know about the CPluginMgr class, as it is declared as a friend in the header. Circular dependancy hell ensues. I see another option, declare the Enable/Disable functions as private members of CPlugin and use boost::dynamic_pointer_cast<CVariantName> instead.
void CPluginMgr::EnablePlugin(PluginPtr plugin)
{
if(plugin->Type == PLUGIN_DSPAUDIO)
{
boost::shared_ptr<CAudioDSP> dsp = boost::dynamic_pointer_cast<CAudioDSP>(plugin);
dsp->Enable();
}
}
This however leads to lots of duplicate code with many multiple variants of the base CPlugin template. If anyone has a better suggestion please share it!
You can easily write :
class CPluginMgr;
class IPlugIn ..
{
friend CPluginMgr;
...
};
Only a predefinition is needed for friend.
I think your get in trouble trying to return a shared_ptr in clone method. Why don't you make use of covariant return types? What you are doing is a common idiom called Virtual Constructor.
class IPlugin
{
public:
virtual IPlugin* clone() = 0;
// ...
}
class CPluginMgr;
class CPlugin : public IPlugin
{
public:
virtual CPlugin* clone() = 0;
friend CPluginMgr; // as #Christopher pointed out
void Enable(bool enable) { m_disabled = !enable; }
// ...
}
class CAudioDSP : public CPlugin
{
public:
virtual CAudioDSP* clone();
// ...
}
CAudioDSP* CAudioDSP::clone()
{
return new CAudioDSP(*this); // assume copy constructors are properly implemented
}
Returning a shared_ptr may lead you to make errors (as early destruction of temparary objects) and I think is not usually a good idea.