"定义"类构造函数中的成员函数

时间:2014-08-19 17:33:52

标签: c++ c++11 constructor member-functions

大家好,

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

假设你有这个简单的课程:

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 )( );
};

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

非常感谢您的回答!

2 个答案:

答案 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显式或隐式)。

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