Pure Virtual function override - c++

Ok so I have a bit of a silly question but I think it might be useful if there was a way to do it.
Anyway, assume I have the following class:
class Foo
{
public:
virtual void Show() = 0;
};
What if I want to use Foo without inherriting? Is there a way to simply do the following (rather than create a whole new class to implement Show):
Foo F;
F.Show = [&]{/*Do something here*/}; //Assign some function or Lambda to Foo instance F
Is there a way to do that? I know it seems silly but I just have to know if that or something similar can be done.
It obviously doesn't compile :l

Is there a way to do that?
No, you can't instantiate Foo if it has a pure virtual member function.
I just have to know if that or something similar can be done.
It depends what you mean by similar. If you forget about the pure virtual, you can give Foo::Show() an implementation in terms of, say, an std::function<void()>, which you can set from a lambda expression, another std::function<void()> or any callable entity with that signature and return type.
#include <functional>
class Foo
{
public:
virtual void Show() { fun(); }
std::function<void()> fun;
};
Then
#include <iostream>
int main()
{
Foo f;
f.fun = []{std::cout << "Hello, World!";};
f.Show();
}
Note as suggested in #MrUniverse's comment, you should check whether the function has been assinged before calling it. This can be easily done:
virtual void Show() { if (fun) fun(); };

Something like that can work :
#include <functional>
#include <iostream>
class Foo
{
public:
std::function<void(void)> Show;
};
int main()
{
Foo f;
f.Show = [&] () { std::cout << "Hello !" << std::endl; };
f.Show();
}

Pure virtual classes can not be instantiated at all

The closest you can get is a local anonymous class:
#include <iostream>
class Foo
{
public:
virtual void Show() = 0;
};
int main() {
struct : Foo {
void Show() {
std::cout << "Hello world\n";
}
} f;
f.Show();
}

You can instead store a function pointer called show in the class.
class Foo
{
public:
void (*Show)();
Foo()
{
Show = 0;
}
}
Then if Show != 0 you can call it (aka if the user assigns a function pointer to it).

Related

C++ Assign a member function of a derived class to a pointer to function of the base class

Following up my previous question about pointers to functions I'd like to ask, what is the difference between the pieces of code below.
This works! I use a pointer to a member function of the class Base. Though I have to call the function through the pointer differently cause it's a pointer to a member and not a pointer to a free function. But it works.
#include <iostream>
class Base;
using Handler = void (Base::*)(int e);
class Base
{
protected:
Base(Handler init)
{
currentState = init;
}
Handler currentState;
};
class Derived : public Base
{
public:
Derived() : Base((Handler)&foo)
{
}
void run(int e)
{
(this->*currentState)(e);
}
private:
void foo(int e)
{
std::cout << "foo function\n";
std::cout << "e = " << e << std::endl;
}
};
int main(void)
{
Derived derived;
derived.run(10);
return 0;
}
Output:
foo function
e = 10
Then I modify the code a little bit and I use pointer to function using Handler = void (*)(int e);
#include <iostream>
class Base;
using Handler = void (*)(int e);
class Base
{
protected:
Base(Handler init)
{
currentState = init;
}
Handler currentState;
};
class Derived : public Base
{
public:
Derived() : Base((Handler)&foo)
{
}
void run(int e)
{
currentState(e);
}
private:
void foo(int e)
{
std::cout << "foo function\n";
std::cout << "e = " << e << std::endl;
}
};
int main(void)
{
Derived derived;
derived.run(10);
return 0;
}
And it does not work, as you can see from the output below
Output:
foo function
e = 679096448
Also, Is that legal in C++? Or I have a piece of code that happens to work? I'm asking that because I'm making a state machine model and I wouldn't like surprises in the middle of development down the line...
EDIT: Adding one more question, Why does the function is called, but the argument value is unspecified?
I think you should use std::function and learn how to use lambdas or std::bind -- I prefer lambdas.
You can define something like this:
#include <functional>
using Comparator = std::function<bool(const MyObject &)>;
And then you can assign a lot of different things to it. You can define either free or static methods. You can use std::bind in order to assign non-static methods. Or you can do what I do, and use a lambda.
void foo(Comparator f) {
if (f(someObject)) {
....
}
}
That part is easy. You can call that like this (for instance):
foo([](const Myobject &obj) { return obj.foo == bar; });
Or:
foo([](const Myobject &obj) { return obj.gleep(); });
Function pointers are a C-ism. std::function is how to do it in C++. It's more powerful. It can do everything a function pointer can do, but it can go further.
I don't care for std::bind, but you can find examples. Lambda syntax isn't necessarily simple, either, but I prefer it.

Using std::bind and std::function to use a class member function as callback for another class member routine

This may have been explored before, but I am not certain how it works out, and how t should in my particular case..
Essentially I have a class, with a callback defined as :
class Foo
{
public:
using someCallbackName = std::function<void(int)>;
void someFunc();
Foo(int, someCallBackName);
private :
someCallbackName m_callBack;
}
void Foo::someFunc()
{
m_callBack(1);
}
I used to call this in main() or by just referencing function of similar signature..
void someOtherFunction(int x)
{
cout << x;
}
int main()
{
Foo::someCallbackName callBack = someOtherFunction;
Foo foo(5, callBack);
}
I decided though, that I may need someOtherFunction as a class member, and put it as part of a class. However, using class member function someOtherFunction as a callback required making it static, which worked fine, but which would mean it wouldn't have access to non-static class members, which sort of defeated the purpose to put it in a class.
I tried using :
C++ callback using class member
and the struct access as given in :
https://en.cppreference.com/w/cpp/utility/functional/bind
..but it does not seem to work, the std::bind to
Foo::someCallbackName callBack = std::bind(not_sure_what_to_use_here);
keeps giving errors saying no suitable conversion, which makes me think that somewhere the signature of callback or mechanism of using std::bind in the code is erroneous.
Keeping class Foo as is, how can m_callBack call someOtherFunction ?
You can "bind" the callback to a non-static member function of a particular object by using labmda:
class X {
public:
void someOtherFunction(int x) const { std::cout << x; }
};
int main()
X x;
Foo::someCallbackName callBack = [&x](int i){ x.someOtherFunction(i); };
Foo foo(5, callBack);
foo.someFunc();
}
Live demo: https://wandbox.org/permlink/fUmrnD6xn1xr7zn0.
To avoid dangling references after x is destroyed, you can employ shared pointers, as follows (note it is captured by value):
Foo::someCallbackName callBack;
{
auto ptr_x = std::make_shared<X>();
callBack = [ptr_x](int i){ ptr_x->someOtherFunction(i); };
}
Foo foo(5, callBack);
foo.someFunc();
Live demo: https://wandbox.org/permlink/23euPcuDUsDENdRe.
As #Daniel Langr said, you can use a lambda function.
Otherwise if you want to use a callback that is a member function you need to bind it to an object.
#include <functional>
#include <iostream>
class Foo
{
public:
using someCallbackName = std::function<void(int)>;
void someFunc();
Foo(int, someCallbackName);
private:
someCallbackName m_callBack;
};
class Bar
{
public:
void someOtherFunction(int x);
};
Foo::Foo(int i, someCallbackName cb)
{
m_callBack = cb;
someFunc();
}
void Foo::someFunc()
{
m_callBack(1);
}
void Bar::someOtherFunction(int x)
{
std::cout << x;
}
int main()
{
Bar bar;
Foo::someCallbackName callBack = std::bind(&Bar::someOtherFunction, &bar, std::placeholders::_1);
Foo foo(5, callBack);
}
Be careful about the lifetime of barwhen doing this.
Oone way to adress the lifetime issue is to make Foo responsible for the lifetime of Bar (this design pattern is called a composition).
#include <functional>
#include <iostream>
// If you declare both class in different files you may need to look into "forward declaration"
class Bar
{
public:
void someOtherFunction(int x);
};
class Foo
{
public:
using someCallbackName = std::function<void(int)>;
void someFunc();
Foo(int, someCallbackName);
private:
someCallbackName m_callBack;
Bar bar;
};
Foo::Foo(int i)
{
m_callBack = std::bind(&Bar::someOtherFunction, &bar, std::placeholders::_1);;
someFunc();
}
// someOtherFunction and someFunc are left unchanged
int main()
{
Foo foo(5);
}

How to get class member function pointer

For one class I want to store some function pointers to member functions of another class. I am trying to return a class member function pointer. Is it possibile?
class one{
public:
void x();
void y();
};
typedef void(one::*PF)(void);
class two :public one{
public:
virtual PF getOneMethodPointer();
};
class three : public two{
std::vector<PF> pointer_to_function;
PF getOneMethodPointer();
pointer_to_function.push_back(getOneMethodPointer())? //how to get method x from class one?
};
In C++11/14, you can always use std::function wrapper to avoid writing unreadable and old C-style function pointers. Here's a simple program with this approach:
#include <iostream>
#include <functional>
using namespace std;
class one {
public:
void x() { cout << "X called" << endl; }
function<void()> getOneMethodPointer();
};
class two : public one {
public:
function<void()> getOneMethodPointer() {
return bind(&one::x, this);
}
};
int main()
{
two* t = new two();
t->getOneMethodPointer()();
delete t;
return 0;
}
As you can see, there's also std::bind used to bind method with std::function. First argument is a reference to the x() method and the second one specifies to which concrete (instantiated) object the pointer is meant to point. Note, that if you say to the st::bind "hey, bind me x() method from one class", it still doesn't know where it is. It knows that - for instance - x() method in this object can be found 20 bytes next to its beginning. Only when you add that it is from for example two* t; object, the std::bind is able to locate the method.
EDIT: Answering to your questions in comments: below code shows an example with virtual getMethodPointer() method:
#include <iostream>
#include <functional>
using namespace std;
class one {
public:
void x() { cout << "X called (bound in one class)" << endl; }
void y() { cout << "Y called (bound in two class)" << endl; }
virtual function<void()> getMethodPointer() {
return bind(&one::x, this);
}
};
class two : public one {
public:
virtual function<void()> getMethodPointer() {
return bind(&one::y, this);
}
};
int main()
{
one* t_one = new one();
one* t_two = new two();
t_one->getMethodPointer()();
t_two->getMethodPointer()();
delete t_one;
delete t_two;
return 0;
}
The C++ syntax for it is this:
class two: public one{
virtual PF getOneMethodPointer(){
return &one::x;
}
};
[Live example]

Assign pointer to a function the address of a pointer to function object

Is it possible in C++?
For example I have a pointer to a function that takes no parameters and its return type is void:
void (*f)();
and and a function object:
class A
{
public:
void operator()() { cout << "functor\n"; }
};
Is it possible to assign to f the address of an A object? And when I call f() to call the A functor?
I tried this but it doesn't work:
#include <iostream>
using namespace std;
class A
{
public:
void operator()() { cout << "functorA\n"; }
};
int main()
{
A ob;
ob();
void (*f)();
f = &ob;
f(); // Call ob();
return 0;
}
I get C:\Users\iuliuh\QtTests\functor_test\main.cpp:15: error: C2440: '=' : cannot convert from 'A *' to 'void (__cdecl *)(void)'
There is no context in which this conversion is possible
Is there any way to achieve this?
You can't do it in the way you've specified, because:
operator() must be a nonstatic function (standards requirement)
a pointer to a non-static function must have an implicit parameter - the pointer to the class instance
your call to f() does not give any indication on which instance of the object A your function is called
Using C++11 and std::function, as Stephane Rolland pointed out, may do the trick - you'll be specifying the pointer to the object in the binding:
std::function<void(void)> f = std::bind(&A::operator(), &ob);
(See question on using std::function on member functions)
If you use C++11, could use std::function
#include <functional>
std::function<void()> f;
int main()
{
A ob;
ob();
f = ob; // f refers to ob
f(); // Call ob();
return 0;
}
Yes it's kind of possible using a C++1/C++0x feature, but to achieve this you should use the std::function which can address to the two types, functions and object functions.
#include <functional>
class A
{
public:
void operator()() { }
};
int main()
{
std::function<void(void)> aFunction;
A ob;
aFunction = ob;
// or as another user said
// aFunction = std::bind(&A:operator(), &ob);
aFunction();
void (*f)();
aFunction = f;
aFunction();
return 0;
}
and if you're stuck with C++03, you could play with std::mem_fun and std::ptr_fun
How about some workaround like this:
Basically you want to have a common way of calling member functions and functions. Then maybe you could create a wrapper that would represent a generic pointer to either a function or member function. Let's say you have Base class and you want to be able to invoke operator() of all derived classes. Then you also have a function() that you want to invoke as well:
class Base
{
public:
virtual void operator()() = 0;
};
class A : public Base
{
public:
void operator()(){ std::cout << "A()" << std::endl; }
};
void function()
{
std::cout << "function" << std::endl;
}
If you create an wrapper that allows you to construct your custom pointer (MyFncPtr):
typedef void (Base::*BaseFncPtr)();
typedef void (*FncPtr)();
class MyFncPtr
{
public:
MyFncPtr(FncPtr f) : fnc(f), baseObj(NULL), baseFnc(NULL) { }
MyFncPtr(BaseFncPtr fPtr, Base* objPtr) : baseFnc(fPtr), baseObj(objPtr), fnc(NULL) { }
void invoke()
{
if (baseObj && baseFnc)
(baseObj->*baseFnc)();
else if (fnc)
fnc();
}
private:
BaseFncPtr baseFnc;
Base* baseObj;
FncPtr fnc;
};
you could achieve it like this:
A a;
MyFncPtr myPtr(&Base::operator(), &a);
myPtr.invoke();
MyFncPtr myPtr2(function);
myPtr2.invoke();
outputs:
A()
function
Hope this helps :)

c++ forward declaration

#include <iostream>
#include <cstring>
using namespace std;
class Obj;
class Test {
friend class Obj;
public:
Test()
{
}
~Test()
{
}
void foo()
{
//print();
//Obj::print();
//Obj x;
//x.print();
}
};
class Obj {
public:
void print()
{
cout << "print here" << endl;
}
};
int main()
{
Test test;
test.foo();
return 0;
}
Quick question,how can I call print the correct way in Test::foo() ?
You need to define the member function after the definition of Obj:
class Test {
public:
void foo();
};
class Obj {
public:
void print() { }
};
void Test::foo() {
Obj o;
o.print();
}
As mentioned by james you should define the member function after the definition of Obj. Also you are calling Obj::print, but print is not a static member function so you must call it on an instance of Obj not Obj itself.
If you really do want print to be a static member, declare it so.
class Obj {
public:
static void print(){ blah }
}
Also you do not need to make Obj a friend in order to access its public methods.
Also can OP please define "correct way", I was assuming you wanted it to be a static member function, james' answer is correct if you want one instance of Obj per instance of Test.
UPDATED
OP, as per your comment you must have the declaration of Obj along with print BEFORE using it within Test. This can be achieved in many ways:
move the entire class Obj defintion (and declaration) before Test
declare Obj's methods with its class definition and define them later.
declare Test like you have and Define Test as per James' post (after Obj).
The following works fine:
#include <iostream>
#include <cstring>
using namespace std;
class Obj {
public:
static void print()
{
cout << "print here" << endl;
}
};
class Test {
public:
Test()
{
}
~Test()
{
}
void foo()
{
Obj::print();
}
};
int main()
{
Test test;
test.foo();
return 0;
}
However it is always nicer (in my opinion) to separate declaration from definition for all but the most trivial of cases.