Let's say, I've two classes
class A
{
public:
void foo( /* ............. */ );
};
class B
{
public:
void bar();
};
I want to know, if it's even possible to pass to the foo method a pointer of bar method, store it in A and run bar later from A. I should say, that A won't know, what class bar is a member of!
I'd appreciate much if you show me the syntax or some link with not that complicated description of the topic.
DESCRIPTION
I'm designing an observer pattern for C++. I want to subscribe B to some events of A. e.g. this code should be in an instance of B
// pseudo code
A* observable = new A();
observable->addEventListener ( 'eventTitle' , functionName );
And when eventTitle occurs A calls functionName of B
There is a couple of methods how to call a pointer to member function, hiding it's origin:
Use std::function and std::bind:
class B {
double Sqrt(int what) { return std::sqrt((double)what); }
};
// in A:
std::tr1::function<double (int)> fn;
fn = std::tr1::bind(&B::Sqrt, &operations, std::tr1::placeholders::_1);
fn(3.1415);
Use a functor, which will wrap the pointer to member function and the object, on which it's to be called, togeter. (This is a bit complicated, though, and in principle is just a subset of what std::function does).
Derive B from an abstract interface IFn and pass B as IFn reference to Foo. Foo will know what to call - a virtual Do() function of the interface.
How can A use a member function of B without knowing anything about it? To call it, you need an object, which has to be o type B (or subtype), so A must have this knowledge.
If you make bar() a static function, you can use regular function pointer (void (*)()) or std::function<void ()> (boost::function for older C++) - of which I would strongly recommend the latter.
That won't work unless bar is declared as a static member of B. You should take into account that you would need an instance of B in order to call any non-static methods.
(Check the C++ FAQ chapter on pointer-to-member-functions for a deeper explanation.)
UPDATE: if you want to implement an observer pattern, you can declare an interface (pure abstract class), say Observer, that A knows and use pointer-to-member-functions to map your events to the corresponding Observer methods.
Example:
A observable;
observable.addEventListener ( 'eventTitle' , &B::functionName );
B observer;
observable.registerObserver(&observer);
Use something like:
class A
{
public:
void foo( /* ............. */ );
void SetObs(CObs *pObs)
{
m_pObs = pObs;
}
private:
CObs *m_pObs;
};
class B : public class CObs
{
public:
virtual void bar();
};
class CObs
{
public:
virtual void bar() = 0;
};
And whenever you need bar() function call m_pObs->bar(). Also derive all slasses like B from CObs and override the function bar().
Related
I'm thinking of the way how to call most base virtual function given a pointer to a base class and pointer to most base virtual function of that class. This call should happen in outher module, e.g. Invoker, this module shouldn't know anything about class and function it's calling.
Need to build event-emitting system that will not respect virtuality of the callbacks and call exactly that target's function which address was passed to Invoker.
I want to make mandatory for derived classes to use their own callbacks and subscriptions and in general don't do virtual callback in the hierachy. If client still needs something alike, he can try to use virtual handlers in non-virtual callback of the base class.
I tried all kind of casts. Doesn't help, maybe I use them wrong...
#include <iostream>
class A
{
public:
virtual void Foobar() { std::cout << "A" << std::endl; }
};
class B : public A
{
public:
virtual void Foobar() { std::cout << "B" << std::endl; }
};
using CallbackType = void(A::*)();
void Invoker(A* target, CallbackType function)
{
(target->*function)();
}
int main()
{
A a;
B b;
Invoker(&a, &A::Foobar);
Invoker(&b, &A::Foobar);
b.A::Foobar(); // how to make similar call inside Invoker(&b, &A::Foobar) ?
return 0;
}
The output will be:
A
B
A
I want Invoker somehow to call the most base function, so expected output is:
A
A
A
It's not possible to do this with a pointer to member function. Instead, a lambda would be more appropriate:
Invoker(&b, [](A& a) { a.A::Foobar(); });
You need to rewrite Invoker as a template so that it can accept both lambdas and pointers to members:
template <class F>
void Invoker(A* target, F&& function) {
std::invoke(std::forward<F>(function), *target);
}
From what I know, it's impossible.
You can't call a virtual function in a non-virtual manner through a member function pointer.
Well, the lambda solution presented in the other answer is indeed the way to go.
However, I found a way to do what you want ... sort of. The downside is that it involves a slicing copy of the object:
void Invoker(A* target, CallbackType function)
{
(static_cast<A>(*target).*function)();
}
or
void Invoker(A target, CallbackType function)
{
(target.*function)();
}
I have issues regarding C++ class inheritance.
I have a class which has virtual method, for example:
class IFoo {
public:
virtual int sayFoo() = 0;
};
And I have several implementations, for example:
class Foo1: public IFoo {
public:
virtual int sayFoo() {
return 1;
}
};
class Foo2: public IFoo {
public:
virtual int sayFoo() {
return 2;
}
};
I want to hold IFoo instance inside a dummy container class (like a sort of wrapper) exposing the same interface of IFoo:
class DummyWrapper : public IFoo {
public:
DummyWrapper(IFoo& foo): foo{foo} {}
virtual int sayFoo() {
return foo.sayFoo(); //ALPHA
}
private:
IFoo& foo; //BETA
};
Normally everything should work, for example, like this:
IFoo& foo = Foo1{};
DummyWrapper wrapper{foo};
wrapper.sayFoo();
My problem is that foo is actually just a r-value that is removed after its scope goes out, like here:
DummyWrapper generateWrapper() {
return DummyWrapper{Foo1{}};
}
This lead to read problems in "ALPHA" line.
A solution would be to put the r-value on the heap and use pointers to access the foo. Since I'm new to C++ and maybe I'm falling into a XY problem, my question is:
is this the only solution? Isn't there a better method to use to solve the issue?
I don't think i can replace "BETA" line with IFoo foo since in this way the DummyWrapper will always store the bytes of a IFoo, not of a IFoo implementation. Or maybe I can use the value IFoo foo to call derived virtual methods?
Thanks for any kind reply
is this the only solution? Isn't there a better method to use to solve the issue?
As soon as polymorphism is involved, unfortunately, yes, it is and no, there isn't. But you get an almost equivalent solution to storing IFoo foo, if you use a smart pointer:
// member:
std::unique_ptr<IFoo> foo;
// constructor:
DummyWrapper(std::unique_ptr<IFoo>&& foo): foo(std::move(foo)) { }
// need to accept r-value ^
// reference: std::unique_ptr is only movable, not copiable!
// for the same reason, you need to preserve the r-value reference
// on assignment to member...
// creation of the wrapper:
return DummyWrapper(std::make_unique<Foo1>(/* arguments for constructor, if there are */));
I don't think i can replace "BETA" line with IFoo foo since in this way the DummyWrapper will always store the bytes of a IFoo, not of a IFoo implementation. Or maybe I can use the value IFoo foo to call derived virtual methods?
Absolutely correct: That's an effect called 'object slicing', at the point you assign a derived object to a base one, all the surplus stuff coming from the derived type gets lost. Pretty common problem (e. g. when people try to store derived objects in a std::vector<Base>).
Usually we create wrapper when we wants to alter the interface of a class or want to implement additional functionalities, for example
std::queue<T> is wrapper/adapter on std::std::deque<T>(by default)
The std::queue<T> class template acts as a wrapper to the underlying container - only a specific set of functions is provided. The queue pushes the elements on the back of the underlying container and pops them from the front.
In your case i don't think you need DummyWrapper you can use IFoo in place of DummyWrapper and it will do the same job.
Let consider following function,
bool isEven( IFoo& ifoo) // Not const& because sayFoo() is not const method.
{
return ( 0 == ( ifoo.sayFoo() % 2)) ;
}
This function will work for all types like Foo1 , Foo2, and no wrapper is required.
I have a class that contains some functions (none are virtual) and 2 more classes publicly inherit that class. In both the sub classes I override the same function of the base class.
After creating objects of all three classes in main (located at the same file), I call the original function with the baseclass object and the overridden functions with the derivedclass objects.
I was expecting all 3 function calls to run the original function from the base class (since I didn't use 'virtual' anywhere in the code), but I actually get each version of that function working according to the class in which it was defined (3 different versions).
I have the classes Base & Derived as follows:
struct Base
{
void foo();
};
struct Derived : Base
{
void foo();
};
in main:
int main()
{
Derived d;
d.foo();
}
I thought d.foo() should run Base::foo() if not using 'virtual'.
This is not "overriding"... and it doesn't need to be.
struct Base
{
void foo();
};
struct Derived : Base
{
void foo();
};
int main()
{
Derived d;
d.foo();
}
If I understand you correctly, then you were expecting this to execute Base::foo(), because the functions are not virtual and therefore one does not override the other.
But, here, you do not need virtual dispatch: the rules of inheritance simply state that you'll get the right function for the type of the object you run it on.
When you need virtual dispatch/overriding is a slightly different case: it's when you use indirection:
int main()
{
Base* ptr = new Derived();
ptr->foo();
delete ptr;
}
In the above snippet, the result will be that Base::foo() is called, because the expression ptr->foo() doesn't know that *ptr is really a Derived. All it knows is that ptr is a Base*.
This is where adding virtual (and, in doing so, making the one function override the other) makes magic happen.
You cannot override something that isn't virtual. Non-virtual member functions are dispatched statically based on the type of the instance object.
You could cheat by "overriding" a function by making it an inline function calling something indirectly. Something like (in C++03)
class Foo;
typedef int foo_sig_t (Foo&, std::string&);
class Foo {
foo_sig_t *funptr;
public:
int do_fun(std::string&s) { return funptr(*this,s); }
Foo (foo_sig_t* fun): funptr(fun) {};
~Foo () { funptr= NULL; };
// etc
};
class Bar : public Foo {
static int barfun(Bar&, std::string& s) {
std::cout << s << std::endl;
return (int) s.size();
};
public:
Bar () : Foo(reinterpret_cast<foo_sig_t*>)(&barfun)) {};
// etc...
};
and later:
Bar b;
int x=b.do_fun("hello");
Officially this is not overloading a virtual function, but it looks very close to one. However, in my above Foo example each Foo instance has its own funptr, which is not necessarily shared by a class. But all Bar instances share the same funptr pointing to the same barfun.
BTW, using C++11 lambda anonymous functions (internally implemented as closures), that would be simpler and shorter.
Of course, virtual functions are in generally in fact implemented by a similar mechanism: objects (with some virtual stuff) implicitly start with a hidden field (perhaps "named" _vptr) giving the vtable (or virtual method table).
Here are the requirements posed by my application. I have a class A, that accepts a function pointer say cFunc, Basically in my implementation of A, I have it call cFunc multiple times.
The cFunc pointer itself should point to different functions depending upon the application. Thus for each application I create a class with the same function definition as cFunc, however I cannot assign the class's member function to this pointer
class A {
typedef double (*Def_CFunc)(std::vector<double>);
A(Def_CFunc _cFunc) { // Some implementation}
// Other Functions
};
class B { double someFunc(std::vector<double> b); };
class C { double someOtherFunc(std::vector<double> a); };
int main () {
B firstObj;
C secondObj;
// Depending upon the situation, I want to select class B or C
double (*funcPointer)(std::vector<double>) = firstObj.someFunc; // Error in this line of code
A finalObj(funcPointer);
}
So how do I make it such that any class with a member function of the given format can be used to initialize the class A?
I'm not sure what exactly your requirements are, but it looks like you want an interface (or abstract base class in C++ lingo).
If both B and C inherit from a common base class, you can pass a pointer to this base class and invoke functions on it:
class I { virtual double func(std::vector<double> a) = 0; }
class B : public I { double func(std::vector<double> a); };
class C : public I { double func(std::vector<double> a); };
You can pass an I* pointer to A and just use i->func.
Pointer to member function has different syntax than pointer to ordinary function and can only point to a method of one given class. To be able to point to methods in different classes use boost::function or if C++11 is available use std::function. These can hold any method or function of a given signature.
What you need is std::function together with either std::bind or lambda expressions (or the Boost equivalent of the first two), because member function pointers don't allow you to do that.
You can do it using std::bind + std::function. Lets write some template class wrapper, that takes any static type as input. Then use this wrapper in free function switch_obj. Usage is very simple.
typedef std::function<double(std::vector<double>)> my_foo;
template<class C>
struct switcher
{
static my_foo convert(C* obj)
{
return my_foo( std::bind(&C::someFunc,obj,std::placeholders::_1) );
}
};
template<class T>
my_foo switch_obj(T* obj)
{
return switcher<T>::convert(obj);
}
void main()
{
B firstObj;
C secondObj;
auto f = switch_obj(&firstObj);
A a(f);
}
Bar and Box are derived classes of Foo and Foo has a virtual function F() and Bar and Box both have function F(). From what I understand, polymorphism correctly allows Bar.F() instead of Box.F() or Box.F() instead of Bar.F() to override Foo.F() using some runtime routine without knowing whether your object is a Bar or a Box. It's something like this:
Foo * boxxy = new Box;
boxxy->F();
The last line will call the right F() (in this case, Box.F()) independent of whether boxxy is a Box or a Bar or a Foo (in which case the implementation of the virtual Foo.F() is called).
Do I understand this right? And what changes if boxxy is a Box pointer? And what happens if the derived class doesn't have an override for F()? Lastly, to avoid implementing a function for a base class but still allow polymorphism, do you just write an empty function body and declare it virtual? Thanks.
Nearly right - consider this inheritance tree:
Foo
/ \
Bar Box
If you now make a pointer like this:
Bar* barry = new Box();
You'll get a nice compiler error, since a Box can't be converted to a Bar. :)
So it's only Foo<->Bar and Foo<->Box, never Bar<->Box.
Next, when boxxy is a Box pointer, it will only ever call the Box::F function, if it is provided.
And last, to force subclasses to implement a certain function, you declare it pure virtual, like this:
virtual void Func() = 0;
// note this --- ^^^^
Now subclasses (in this case Bar and Box), must implement Func, else they will fail to compile.
Yes the right F() will be called dependent on the type of object you have created through your Foo pointer.
If boxxy were a Box pointer you could only call it's F() or one of it's derived class's F(), unless you did a dynamic_cast to it's parent class and then called F().
To avoid having to implement in the base class you define it as pure virtual like so:
class Foo
{
public:
virtual void F() = 0; //notice the = 0, makes this function pure virtual.
};
And what changes if boxxy is a Box
pointer?
It will allow access to the methods of Box not inherited from Foo. Box pointer can't point to Bar objects, since Bar isn't derived from Box.
And what happens if the derived class
doesn't have an override for F()?
It will inherit the implementation of F() from the base class.
Lastly, to avoid implementing a
function for a base class but still
allow polymorphism, do you just write
an empty function body and declare it
virtual?
It will work, but it is not a right way to do polymorphism. If you can't come up with a concrete implementation for the virtual function of the base class make that function pure virtual, don't implement it as empty function.
If you declare Foo like this
class Foo
{
private:
Foo() {};
public:
void func() const { std::cout << "Calling Foo::func()" << std::endl; }
};
and Bar like this
class Bar : public Foo
{
private:
Bar() {};
public:
void func() const { std::cout << "Calling Bar::func()" << std::endl; }
};
then
Foo* bar = new Bar();
bar->func();
will call Foo::func().
If you declare Foo like this
class Foo
{
private:
Foo() {};
public:
virtual void func() const { std::cout << "Calling Foo::func()" << std::endl; } // NOTICE THE virtual KEYWORD
};
then
Foo* bar = new Bar();
bar->func();
will call Bar::func().
Do I understand this right? Yes, if the function was declared as a virtual function.
And what changes if boxxy is a Box
pointer? Depends on whether the
function is virtual or not. A virtual
function will always end up calling
the proper derived function; a
non-virtual function will call the
version based on the type of the
pointer.
And what happens if the derived class
doesn't have an override for F()? It
will use the base class definition.
Lastly, to avoid implementing a
function for a base class but still
allow polymorphism, do you just write
an empty function body and declare it
virtual? You can also declare it pure
virtual: virtual void F() = 0. Any
class that intends to be instantiated
into an object much override this
function and give it a proper
implementation.