I have the following code, where the execute()
method accepts a function as a parameter and executes it. The start()
method then calls execute()
in order to run method1()
.
class Test
{
int Test::start(void)
{
execute(&Test::method1);
return 1;
}
void Test::execute(void(Test::*func)(void))
{
(this->*func)();
}
void Test::method1(void)
{
//Do something...
}
}
Now I want to modify this so I achieve the following:
TestRunner
and and move the execute()
method to it Test
inherit from TestRunner
, where it can call the execute()
method to run its local methods I am trying the following, but got stuck in how I should specify the method parameter in execute()
ie what right now I have as TestRunner::*func
.
class TestRunner
{
public:
TestRunner()
{
//Do something...
}
protected:
void execute(void(TestRunner::*func)(void))
{
(this->*func)();
}
}
class Test : TestRunner
{
public:
Test() : TestRunner()
{
}
int start()
{
TestRunner::execute(&Test::method1);
return 1;
}
private:
void method1(void)
{
//Do something
}
}
If I compile the code like it is I obviously get these errors:
no matching function for call to 'Test::execute(void (Test::*)())'
and
no known conversion for argument 1 from 'void (Test:: )()' to 'void (TestRunner:: )()'
Can anyone guide me in the right direction here or do I need to do something completely different to achieve what I want?
I've used this answer here to come up with a solution: C++ Pointers to Member Functions Inheritance
Create a callback class:
class Callback
{
public:
virtual ~Callback() { }
virtual void doSomething()=0;
};
Extend the callback class to define how a function is executed and use a template:
template<class T>
class BCallback: Callback
{
public:
~BCallback() { }
BCallback(T *obj, void(T::*fn)()): obj_(obj), fn_(fn) { };
void doSomething()
{
(obj_->*fn_)();
}
private:
T *obj_;
void(T::*fn_)();
};
Use a callback object in the base class:
class TestRunner
{
protected:
void execute(Callback *cb)
{
cb->doSomething();
}
};
Run the method from the derived class:
class Test: TestRunner
{
public:
int start()
{
BCallback<Test> cb(this, &Test::method1);
this->execute(&cb);
return 1;
}
private:
void method1(void)
{
//Do something
}
};
You can use a typedef
like this:
typedef void(Test::*Callback)(void);
You can then make your executing function take objects of type Callback
. It will look like this Test::execute(Callback)
.
When calling it, use static_cast<>
:
Test tester;
tester.execute(static_cast<Callback>(&DerivedTest::someMethod));
Example Test::execute(Callback)
implementation:
Test::execute(Callback cb) {
(this->*cb)();
}
This way you can avoid writing whole two new classes (one of them a template, even!) just to do a simple thing. As a bonus, you can use function overloading to get Test::execute
for different function signatures.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.