"Define"类构造函数中的成员函数

"Define" a member function in class constructor

本文关键字:成员 函数 构造函数 Define      更新时间:2023-10-16

大家好,

我想知道你是否能够定义或实例化一个函数,例如在一个类的构造函数。

假设你有这样一个简单的类:

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"是否为真。

我想了想,想到了两个可能的解决方案:

#include <iostream>
class iTest {
public:
    virtual void someFunc() = 0;
};
class cTest1 : public iTest {
public:
    void someFunc() { std::cout << "functionBody1n"; }
};
class cTest2 : public iTest {
public:
    void someFunc() { std::cout << "functionBody2n"; }
};

2)使用函数指针:

#include <iostream>
class cTest {
public:
    cTest( bool bla );
    ~cTest() {}
    void someFunc();
private:
    void ( cTest::*m_functionPointer )();
    void function1() { std::cout << "functionBody1n"; }
    void function2() { std::cout << "functionBody2n"; }
};
cTest::cTest( bool bla ) {
    if( bla )
        m_functionPointer = &cTest::function1;
    else
        m_functionPointer = &cTest::function2;
};
void cTest::someFunc() {
    ( *this.*m_functionPointer )( );
};

在我需要这个的程序中,我不能使用继承,也不想使用函数指针。所以我的问题是,是否有另一种(优雅的)方法来做到这一点,例如在类的构造函数中定义函数?

非常感谢你的回答!

如果你不喜欢函数指针,你可以使用function:

#include <functional>

在类的私有部分,不定义函数指针,而是定义函数包装器:

private:
    std::function<void()> m_function;

然后可以在构造函数中使用lambda函数动态初始化这个函数包装器:

if (bla)
    m_function = [this]() { std::cout << id << "functionBody1n";   };
else
    m_function = [this]() { std::cout << id << "functionBody2n";  };

注意,为了能够访问类成员,您应该捕获[this]

然后将someFunc()的定义改为:
void cTest::someFunc() {
    m_function();
};

性能注意事项:

如果您有性能关键问题,您应该做几个基准测试,以确保选择正确的解决方案。这里是在core 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看起来不同。

如果函数体是根据运行时构造函数的参数(bla)设置的,那么不可避免地需要一些间接的,可以是虚表(当使用继承时)或某种函数指针(通过std::function显式或隐式)。

是的,这确实对你的效率有一些(通常很小的)影响。因此,如果函数体很小(并且执行速度很快)并且经常调用(即性能关键),您可能不想使用这种结构(函数体取决于运行时参数)。