大家好,
我想知道你是否能够在一个类的构造函数中定义或实例化一个函数。
假设你有这个简单的课程:
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;
}
如果someFunc是一个经常调用的函数,那么每次调用函数时都可以避免测试“bla”是否为真。
我想到了这一点,我想到了两种可能的解决方案:
1)使用继承:
#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)使用函数指针:
#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 )( );
};
在我需要它的程序中,我不能使用继承,也不想使用函数指针。 所以我的问题是,是否有另一种(优雅的)方法来做到这一点,例如在类的构造函数中定义函数?
非常感谢您的回答!
答案 0 :(得分:3)
如果你不喜欢函数指针,你可以使用函数:
#include <functional>
在类的私有部分中,不是定义函数指针,而是定义函数包装器:
private:
std::function<void()> m_function;
然后,您可以使用lambda函数在构造函数中动态初始化此函数包装器:
if (bla)
m_function = [this]() { std::cout << id << "functionBody1\n"; };
else
m_function = [this]() { std::cout << id << "functionBody2\n"; };
请注意,您应该捕获[this]
以便能够访问类成员。
并将someFunc()的定义更改为:
void cTest::someFunc() {
m_function();
};
效果考虑因素:
如果您有性能问题,那么您应该做一些基准测试,以确保选择正确的解决方案。这里是在核心i7上使用MSVC2013的发布模式,我获得了10 000 000个循环:
15 ms for the function wrapper
31 ms for the function pointer
16 ms for the traditional if/else in the function body.
在调试模式(未优化)中,它与1766,625和297的外观不同。
答案 1 :(得分:0)
如果根据运行时的构造函数的参数(bla
)设置了函数体,那么不可避免地你需要一些间接,无论是虚拟表(使用继承时)还是某种函数指针(通过std::function
显式或隐式)。
是的,这确实会对您的效率产生一些影响(通常很小)。因此,如果函数体很小(并且执行速度很快)经常调用和(即性能关键),您可能不希望使用这样的构造(函数体取决于运行时参数)。