Reputation: 41
Hello all together,
I'm wondering if you are able to define or instantiate a function for example in the constructor of a class.
Let's say you have this simple class:
class cTest {
public:
cTest( bool bla );
~cTest() {}
void someFunc() {}
};
cTest::cTest( bool bla ) {
if( bla ) {
someFunc = functionBody1;
// or
someFunc {
functionBody1
};
// or something different
} else
someFunc = functionBody2;
}
if someFunc is an often called function, you could avoid testing whether "bla" was true or not every time the function gets called.
I thought about it and two possible solutions came to my mind:
1) Using inheritance:
#include <iostream>
class iTest {
public:
virtual void someFunc() = 0;
};
class cTest1 : public iTest {
public:
void someFunc() { std::cout << "functionBody1\n"; }
};
class cTest2 : public iTest {
public:
void someFunc() { std::cout << "functionBody2\n"; }
};
2) Using function pointers:
#include <iostream>
class cTest {
public:
cTest( bool bla );
~cTest() {}
void someFunc();
private:
void ( cTest::*m_functionPointer )();
void function1() { std::cout << "functionBody1\n"; }
void function2() { std::cout << "functionBody2\n"; }
};
cTest::cTest( bool bla ) {
if( bla )
m_functionPointer = &cTest::function1;
else
m_functionPointer = &cTest::function2;
};
void cTest::someFunc() {
( *this.*m_functionPointer )( );
};
In the program where I need this I cannot use inheritance and don't want to use function pointers. So my question is, is there another (elegant) way to do this, e.g. defining the function in the constructor of the class?
Thanks a lot for your answers!
Upvotes: 4
Views: 1723
Reputation: 73366
If you don't like function pointers, you could use functions:
#include <functional>
In the private part of your class, instead of defining a function pointer, define a function wrapper:
private:
std::function<void()> m_function;
You can then initialize this function wrapper dynamically in your constructor with a lambda function:
if (bla)
m_function = [this]() { std::cout << id << "functionBody1\n"; };
else
m_function = [this]() { std::cout << id << "functionBody2\n"; };
Note that you should capture [this]
in order to be able to accesss to class members.
And change the definition of your someFunc() to:
void cTest::someFunc() {
m_function();
};
Performance considerations:
If you have performance critical questions, you should do a couple of benchmarks to be sure to choose the right solution. Here in release mode with MSVC2013 on a core i7 what I get for 10 000 000 loops:
15 ms for the function wrapper
31 ms for the function pointer
16 ms for the traditional if/else in the function body.
In debug mode (unoptimized), it looks differently with 1766, 625 and 297 respecively.
Upvotes: 3
Reputation: 45414
If the function body is set depending on the argument (bla
) to the constructor at run-time, then unavoidably you need some indirection, be it a virtual table (when using inheritance) or some sort of function pointer (either explicitly or implicitly via std::function
).
And yes, this does have some (usually small) impact on your efficiency. So if the function body is small (and fast to execute) and called often (i.e. performance critical), you may not want to use such a construction (function body depending on a run-time argument).
Upvotes: 0