I'm trying to see if the following is possible. I'm still on an old Visual Studio 2008 C++ compiler, so bear with me.
Say, I have two classes derived from a single class. Both have the same function that I want to pass as a pointer to be called from a static function.
Here's pseudocode:
class CDlg1 : public CDialog
{
virtual void func1(int v)
{
wprintf(L"CDlg1::func1 was called, v=%d\n", v);
}
void do_delayed_call()
{
delayed_call_func1(func1);
}
}
class CDlg2 : public CDialog
{
virtual void func1(int v)
{
wprintf(L"CDlg2::func1 was called, v=%d\n", v);
}
void do_delayed_call()
{
delayed_call_func1(func1);
}
}
static void delayed_call_func1(void* pfn)
{
//... some additional action
//int v = something
//Call pfn() after a delay
pfn(v);
}
I can't figure out, do I need to template for this function pointer?
It's hard to know what's going on without seeing code for CDialog. Is "func1" virtual in CDialog? If so, you can write:
void delayed_call_func1(CDialog& cdialog)
{
... ;
cdialog.func1(v);
}
If not, you could indeed use a template:
template <typename CDlgX>
void delayed_call_func1(CDlgX* p)
{
... ;
p->func1(v);
}
Or, if your old compiler can compile boost, there are several libraries therein such as boost::function that are similar to the C++11 std::function, and can be used to supply delayed_call_func1 with an arbitrary callback to your member function, but I'd suggest you only look into that after updating your compiler - then you can use lambdas too.
Related
I am working on a C++ Arduino sketch that creates a GUI on an OLED display. I want to have buttons buttons that all do different things when you press them. In Java, I can simply override the method when creating an anonymous class like this:
class Example {
public void method() {
}
}
Example e = new Example() {
#Override
public void method() {
//do something
}
};
So my question is: Can I do this in an C++?
As arduino sketch are in fact C/C++, you could do the same as in Java.
class Button {
virtual void push() = 0;
}
class PowerButton : public Button {
virtual void push() {
shutdown();
}
}
Notice the virtual keyword, it's used to declare a method overidable, the "= 0" means pure virtual (the address of the method is 0). It simply says that this method is not implemented in this class, the class became abstract as in Java.
Also, the virtual keyword is not mandatory, but if you don't put it, C++ will just call the method of the given type and not from the real type.
Take a look there
But, the difference with Java is that you can't create an anonymous class directly in the code. Instead, maybe take a look for lambda.
For example, the class Button would became :
class Button {
public:
Button(const std::function<void()> &pushCallback) :
mPushCallback(pushCallback) {}
void push() { mPushCallback(); }
private:
const std::function<void()> mPushCallback;
And then the usage:
Button powerButton([]() {
powerOff();
});
Brackets are use to "capture" a variable, for example this, &str { myMethodInMyClass(str); }
Parenthesis are used to pass parameters
The std::function class take the function type as type parameter, a function that take a string as const ref and an int and that return an int will look like this : std::function<int(const std::string &, int)>
I'm making a class which has a method that launches some threads of member functions in the same class. I'm quite new to threads in c++, especially when classes are involved but this is what iv'e come up with.
class A
{
public:
void StartThreads()
{
std::thread fooThread(&A::FooFunc, this);
fooThread.join();
}
protected:
virtual void FooFunc()
{
while (true)
std::cout << "hello\n";
}
};
My question is, if i can get the name of the current object, because now if i create a class B which inherits from A but overwrites FooFunc, FooFunc from class A will be called when i do:
B b;
b.StartThreads();
So i'm looking for a way to replace std::thread fooThread(&A::FooFunc, this) with something like std::thread fooThread(&this->GetClass()::FooFunc, this). I could just make StartThreads virtual and overwrite it in derived classes, but It would be better just to write it once and being done with it. Is there a way to do this or something that results in the same thing?
In case of that your this is known at compile-time then static metaprogramming to the rescue.
C++, Swift and Rust (and now Scala also) are static languages that has a lot of compile time tricks to do for problems like that.
How? In your case templates could help you.
Also, you don't need it to be a member function, it can be a friend function (so that you can easily use templates).
class A
{
public:
template<typename T>
friend void StartThreads(const T& obj);
protected:
virtual void FooFunc()
{
while (true)
std::cout << "hello\n";
}
};
template<typename T>
void StartThreads(const T& obj) {
std::thread fooThread(&T::FooFunc, obj);
fooThread.join();
}
WARNING: This ONLY works if the class is known at compile time, i.e.
class B: public A {
};
...
B b;
A &a = b;
StartThreads(a); // Will call it AS IF IT IS A, NOT B
Another solution:
Functional programming to the rescue, you can use lambdas (or functors using structs if you are on C++ prior to C++11)
C++11:
void StartThreads()
{
std::thread fooThread([=](){ this->FooFunc(); });
fooThread.join();
}
C++98:
// Forward declaration
class A;
// The functor class (the functor is an object that is callable (i.e. has the operator (), which is the call operator overloaded))
struct ThreadContainer {
private:
A &f;
public:
ThreadContainer(A &f): f(f) {}
void operator() ();
};
class A
{
public:
// To allow access of the protected FooFunc function
friend void ThreadContainer::operator() ();
void StartThreads()
{
// Create the functor
ThreadContainer a(*this);
// Start the thread with the "call" operator, the implementation of the constructor tries to "call" the operand, which here is a
std::thread fooThread(a);
fooThread.join();
}
protected:
virtual void FooFunc()
{
while (true)
std::cout << "hello\n";
}
};
class B: public A {
protected:
virtual void FooFunc() {
while(true)
std::cout << "overridden\n";
}
};
void ThreadContainer::operator() () {
f.FooFunc();
}
You've looked at using a virtual FooFunc() directly, and somehow surmised that it doesn't work. (I won't address the accuracy of that here, as that is being brought up in the question's comments.) You don't like the idea of moving the virtual function earlier in the process. So why not move it later? There is a somewhat-common paradigm out there that uses non-virtual wrappers to virtual functions. (Usually the wrapper is public while the virtual function is protected or private.) So, something like:
class A
{
public:
void StartThreads()
{
std::thread fooThread(&A::FooFuncCaller, this); // <-- call the new function
fooThread.join();
}
protected:
void FooFuncCaller() // <-- new function layer
{
FooFunc();
}
virtual void FooFunc()
{
while (true)
std::cout << "hello\n";
}
};
Of course, if the direct call to the virtual Foofunc works, might as well use that. Still, this is simpler than using templates or custom functor classes. A lambda is a reasonable alternative, with the benefit of not changing your class' interface (header file).
Thanks for all of your answers, it turned out that my question was unrelated and that i messed up some other members in the class.
Thanks for your answers giving me some insight into other ways you can do the same thing using different methods. (https://stackoverflow.com/users/9335240/user9335240)
I am working on game engine as a project during the summer. Every scriptable component should have access to some methods in the scene which they are in. To make this possible i pass lambdas from the scene that calls the respective methods to the scriptable where they are implicitly converted to std::function types.
Scene.h:
class Scene
{
private:
unsigned int _currentId;
std::vector<System*> _systems;
//SCRIPTABLE NEEDS THE BELOW METHODS THESE EXCLUSIVELY:
bool exists(unsigned id);
void destroy(unsigned int);
void addComponent(Component*, unsigned int);
template<typename T> T& getComponent(unsigned int);
template<typename T> bool hasComponent(unsigned int);
template<typename T> void removeComponent(unsigned int);
protected:
unsigned int instantiate(std::vector<Component*>);
public:
Scene(ChangeSceneCallback);
~Scene();
void initiate();
void update(long dt);
};
template<typename T>
inline T & Scene::getComponent(unsigned int id)
{
for (System* system : _systems) {
if (system->corresponds(T)) {
return static_cast<T*>(system->getComponent(entityId));
}
}
}
template<typename T>
inline bool Scene::hasComponent(unsigned int id)
{
for (System* system : _systems) {
if (system->corresponds(T)) {
return system->contains(id);
}
}
}
template<typename T>
inline void Scene::removeComponent(unsigned int id)
{
for (System* system : _systems) {
if (system->corresponds(T)) {
return system->destroy(id);
}
}
}
The callback method works for the non-template functions i need access to, but not the templated ones, so it's out of the question.
Scriptable:
typedef std::function<void(int)> ChangeSceneCallback;
typedef std::function<int(std::vector<Component*>)> InstantiateCallback;
typedef std::function<void(int)> DestroyCallback;
typedef std::function<bool(int)> ExistCallback;
typedef std::function<void(Component*, unsigned int)> AddComponentCallback;
class Scriptable: public Component
{
protected:
ChangeSceneCallback changeScene;
InstantiateCallback instantiate;
DestroyCallback destroy;
ExistCallback exists;
public:
~Scriptable();
Scriptable();
void assignCallbacks(ChangeSceneCallback, InstantiateCallback etc ...);
virtual void init() = 0;
virtual void update() = 0;
};
Scriptable can't have access to public methods in scene because this would give the user / developer access to them (Scriptable is a base class for the behaviour of the game). That is why i need to come up with something that gives scriptable limited access to scene.
Any thoughts?
You cannot have a type erased "template callback". You have to choose between the template or the type erasure. Let me explain.
This is what a "template callback" look like. This is in fact a generic lambda:
auto print_callback = [](auto var) {
std::cout << var << std::endl;
}
print_callback(4) ; // prints "4"
print_callback(4.5); // prints "4.5"
print_callback("hello"); // prints "hello"
It seems good but notice that you can't do that with std::function, since you have to predefine the signature.
std::function<void(int)> func_print_callback = print_callback;
func_print_callback(5); // Yay! Prints "5"
func_print_callback("hello"); // error
The thing is, you might think the limitation is only because std::function need a specific signature to work with, but the limitation is much deeper than that.
The thing is, the is no template function. They don't exists. Function template on the other hand, do exist. Why I emphasize so much on the order of my words is because the name of this thing says it all: it is not a function, it a template that is used to make functions.
Here's a simple example:
template<typename T>
void foo(T t) {
std::cout << t << std::endl;
}
This function is not compiled. Because it's not a function. No function foo will exist until the hole T has been filled.
How do you fill the hole named T supposed to be a type?
By filling it with a type of course!
foo(5.4); // the hole T is `double`
When the compiler sees this, it knows you need a function named foo that takes a double as parameter. There is no function named foo that takes a double. But we gave the compiler a tool to create one: the template!
So the compiler will generate this function:
void foo_double(double t) {
std::cout << t std::endl;
}
The word here is this: generate. The compiler need to create the function in order to exist. The compiler generate code for you.
When the function is generated and compiled, T do not exist anymore. A template parameter is a compile-time entity, and only the compiler knows about them.
Now, I'll explain to you why there is no such thing as a template callback.
Type erased container such as std::function are implemented with pointer to function. I'll use type aliases to ease the syntax a bit. It works like this:
// A function
void foo(int) {}
// The type of the pointer to function
using func_ptr = void(*)(int);
// A pointer to foo
func_ptr ptr = &foo;
The pointer to the function foo has a value that points to the location of foo in the memory.
Now imagine we have a way to have template function pointer. We would have to point to a function that does not exist yet. It has no memory location, so it cannot make sense. And through the pointer, when invoked as a function, you'd have to generate the function code.
Since a pointer to function can point to any function, even functions that aren't known to the compiler yet, you'd have to somehow generate the function code and compile it. But the value of the pointer, to which function our pointer points to, is defined at runtime! So you'd have to compile code at runtime, for code that you don't know yet, from a value that does not exist, when the compiler don't exist anymore. As you can see, pointer to template function, template std::function or virtual template function cannot exist.
Now that you have understood the problem, let me propose a solution: drop the callback usage. You should call those functions directly.
You seem to use callback only to be able to call private member functions. This is the wrong way to do it, even if it works. What you need is friend, the feature of C++ that allows you to access private members.
class Scene {
friend Component;
// ...
};
class Component {
protected:
// Let `scene` be a reference to your scene
void addComponent(Component* c, unsigned int id) {
scene.addComponent(c, id);
}
template<typename T>
T& getComponent(unsigned int id) {
return scene.getComponent<T>(id);
}
template<typename T>
bool hasComponent(unsigned int id) {
return scene.hasComponent(id);
}
template<typename T>
void removeComponent(unsigned int id) {
removeComponent(id);
}
// ...
};
Since the Component class is the only friend to Scene, only it can call private member functions. Since all those newly defined functions in Component are protected, only class that extends from Component can call those. They are invoked like this:
class Scriptable : public Component {
void foo() {
hasComponent<Bar>(87); // works, call function defined in `Component`
}
};
I'm new to C++ and am trying to achieve the following design.
class A { do (); doMore (); } // abstract
class B { do (); doMore (); } // abstract
class X : public A, public B // Also abstract
{
foo() {
// common code
A::do();
A::doMore();
}
bar() {
// common code
B::do();
B::doMore();
}
}
Both A and B provide implementations of do() and doMore().
How can I extract the common code that the new function takes an arg that calls the method in the correct parent class?
Something like
X::newMethod(arg_that_indicates_parent_class) {
// common code
arg_that_indicates_parent_class::do();
arg_that_indicates_parent_class::doMore();
}
Then call it like so
newMethod(pass_A_somehow);
newMethod(pass_B_somehow);
Looks like runtime polymorphism, but not quite (or is it?)... as it is within a child class...
Is this design itself just trash and there is a better way to achieve this?
If the idea is that do and doMore will be present in both A and B and those are the functions specifically you wish to call, you could
use a template function like so:
class X : public A, public B // Also abstract
{
template <typename T>
void newMethod()
{
T::do();
T::doMore();
}
}
Then using it explicitly, you could then do it like so:
X x;
x.newMethod<A>();
x.newMethod<B>();
This has the added benefit of catching some errors at compile time, that is, if you try and pass a C and it does not have
the do and doMore functions defined, you will receive a complier error (instead of a run-time crash).
This also lets you utilize the std::enable_if functionality if you are using C++1x.
Hope that can help.
Just factor out the "common code", and make it, well, common:
class X : public A, public B // Also abstract
{
void foo() {
commoncode();
A::do();
A::doMore();
}
void bar() {
commoncode();
B::do();
B::doMore();
}
void commoncode()
{
// Your common code
}
}
That's the most simple, straightforward way. Another alternative way would be closer in line to your "pass me a pointer of some kind" intended approach:
class X : public A, public B // Also abstract
{
void call_a()
A::do();
A::doMore();
}
void call_b()
B::do();
B::doMore();
}
void commoncode( void (X::*ptr)() )
{
// Your common code
(this->*ptr)();
}
}
And the parameter to commoncode() would be either
&X::call_a
or
&X::call_b
Is there some library that allows me to easily and conveniently create Object-Oriented callbacks in c++?
the language Eiffel for example has the concept of "agents" which more or less work like this:
class Foo{
public:
Bar* bar;
Foo(){
bar = new Bar();
bar->publisher.extend(agent say(?,"Hi from Foo!", ?));
bar->invokeCallback();
}
say(string strA, string strB, int number){
print(strA + " " + strB + " " + number.out);
}
}
class Bar{
public:
ActionSequence<string, int> publisher;
Bar(){}
invokeCallback(){
publisher.call("Hi from Bar!", 3);
}
}
output will be:
Hi from Bar! 3 Hi from Foo!
So - the agent allows to to capsule a memberfunction into an object, give it along some predefined calling parameters (Hi from Foo), specify the open parameters (?), and pass it to some other object which can then invoke it later.
Since c++ doesn't allow to create function pointers on non-static member functions, it seems not that trivial to implement something as easy to use in c++. i found some articles with google on object oriented callbacks in c++, however, actually i'm looking for some library or header files i simply can import which allow me to use some similarily elegant syntax.
Anyone has some tips for me?
Thanks!
The most OO way to use Callbacks in C++ is to call a function of an interface and then pass an implementation of that interface.
#include <iostream>
class Interface
{
public:
virtual void callback() = 0;
};
class Impl : public Interface
{
public:
virtual void callback() { std::cout << "Hi from Impl\n"; }
};
class User
{
public:
User(Interface& newCallback) : myCallback(newCallback) { }
void DoSomething() { myCallback.callback(); }
private:
Interface& myCallback;
};
int main()
{
Impl cb;
User user(cb);
user.DoSomething();
}
People typically use one of several patterns:
Inheritance. That is, you define an abstract class which contains the callback. Then you take a pointer/reference to it. That means that anyone can inherit and provide this callback.
class Foo {
virtual void MyCallback(...) = 0;
virtual ~Foo();
};
class Base {
std::auto_ptr<Foo> ptr;
void something(...) {
ptr->MyCallback(...);
}
Base& SetCallback(Foo* newfoo) { ptr = newfoo; return *this; }
Foo* GetCallback() { return ptr; }
};
Inheritance again. That is, your root class is abstract, and the user inherits from it and defines the callbacks, rather than having a concrete class and dedicated callback objects.
class Foo {
virtual void MyCallback(...) = 0;
...
};
class RealFoo : Foo {
virtual void MyCallback(...) { ... }
};
Even more inheritance- static. This way, you can use templates to change the behaviour of an object. It's similar to the second option but works at compile time instead of at run time, which can yield various benefits and downsides, depending on the context.
template<typename T> class Foo {
void MyCallback(...) {
T::MyCallback(...);
}
};
class RealFoo : Foo<RealFoo> {
void MyCallback(...) {
...
}
};
You can take and use member function pointers or regular function pointers
class Foo {
void (*callback)(...);
void something(...) { callback(...); }
Foo& SetCallback( void(*newcallback)(...) ) { callback = newcallback; return *this; }
void (*)(...) GetCallback() { return callback; }
};
There are function objects- they overload operator(). You will want to use or write a functional wrapper- currently provided in std::/boost:: function, but I'll also demonstrate a simple one here. It's similar to the first concept, but hides the implementation and accepts a vast array of other solutions. I personally normally use this as my callback method of choice.
class Foo {
virtual ... Call(...) = 0;
virtual ~Foo();
};
class Base {
std::auto_ptr<Foo> callback;
template<typename T> Base& SetCallback(T t) {
struct NewFoo : Foo {
T t;
NewFoo(T newt) : t(newt) {}
... Call(...) { return t(...); }
};
callback = new NewFoo<T>(t);
return this;
}
Foo* GetCallback() { return callback; }
void dosomething() { callback->Call(...); }
};
The right solution mainly depends on the context. If you need to expose a C-style API then function pointers is the only way to go (remember void* for user arguments). If you need to vary at runtime (for example, exposing code in a precompiled library) then static inheritance can't be used here.
Just a quick note: I hand whipped up that code, so it won't be perfect (like access modifiers for functions, etc) and may have a couple of bugs in. It's an example.
C++ allows function pointers on member objects.
See here for more details.
You can also use boost.signals or boost.signals2 (depanding if your program is multithreaded or not).
There are various libraries that let you do that. Check out boost::function.
Or try your own simple implementation:
template <typename ClassType, typename Result>
class Functor
{
typedef typename Result (ClassType::*FunctionType)();
ClassType* obj;
FunctionType fn;
public:
Functor(ClassType& object, FunctionType method): obj(&object), fn(method) {}
Result Invoke()
{
return (*obj.*fn)();
}
Result operator()()
{
return Invoke();
}
};
Usage:
class A
{
int value;
public:
A(int v): value(v) {}
int getValue() { return value; }
};
int main()
{
A a(2);
Functor<A, int> fn(a, &A::getValue);
cout << fn();
}
Joining the idea of functors - use std::tr1::function and boost::bind to build the arguments into it before registering it.
There are many possibilities in C++, the issue generally being one of syntax.
You can use pointer to functions when you don't require state, but the syntax is really horrid. This can be combined with boost::bind for an even more... interesting... syntax (*)
I correct your false assumption, it is indeed feasible to have pointer to a member function, the syntax is just so awkward you'll run away (*)
You can use Functor objects, basically a Functor is an object which overloads the () operator, for example void Functor::operator()(int a) const;, because it's an object it has state and may derive from a common interface
You can simply create your own hierarchy, with a nicer name for the callback function if you don't want to go the operator overloading road
Finally, you can take advantage of C++0x facilities: std::function + the lambda functions are truly awesome when it comes to expressiveness.
I would appreciate a review on lambda syntax ;)
Foo foo;
std::function<void(std::string const&,int)> func =
[&foo](std::string const& s, int i) {
return foo.say(s,"Hi from Foo",i);
};
func("Hi from Bar", 2);
func("Hi from FooBar", 3);
Of course, func is only viable while foo is viable (scope issue), you could copy foo using [=foo] to indicate pass by value instead of pass by reference.
(*) Mandatory Tutorial on Function Pointers