5

I am a novice c++ programmer who kept an idea that function pointers are a thing of C and OOP in C++ does not recommend its usage.

I know what I write here is vague/broad. But it will be great if somebody could comment whether my idea is completely wrong or something sensible.

Thanks.

  • 1
    Its not really clear what you're trying to achieve with function pointers? – Matt D Oct 7 '13 at 11:51
  • I am asking it generally. Sorry for being vague here. Just like C++ recommend usage of const instead of #define, in a similar way is there any recommendation not to use function pointers. – NeonGlow Oct 7 '13 at 11:53
  • 2
    Not really. There's nothing inherently bad about function pointers. There's always bad usage of them however ;) (other than the cache miss you'll probably get with your instruction cache) – Matt D Oct 7 '13 at 12:00
  • 3
    @NeonGlow There is no rule saying you shouldn't use them, but there are probably ways of structuring your code in such a way that you don't need them. It all depends on the problem you're trying to solve. – James Oct 7 '13 at 12:16
  • 2
    What about std::function (in the <functional> header)? – hlt Oct 7 '13 at 16:53
17

I don't think there is any widely accepted advice to avoid function pointers however there are some alternatives.

Virtual methods One of the most common uses of function pointers in C is to implement dynamic dispatch. In C++ however this can be done for you (for single dispatch) by using virtual functions, indeed the usual implementation is that the compiler creates essentially a table of function pointers.

Functors

in the C++ sense, a functor is a small utility class that overloads operator() to behave like a first class function, as it's a normal class you can pass its objects around like any other objects without need for function pointers.

Lambdas

essentially provide a more convenient way to declare functors inline.

Templates

Provide a generic way to use/consume function pointers, functors or lambdas. So you can write higher order functions without needing function pointers, either by using a std::function parameter or directly using a template parameter.

  • 3
    Might be useful to mention std::bind and std::function<ReturnType(ArgsTypes)>. The first creates functors and the second is a generic functor holder. – MSalters Oct 7 '13 at 16:19
  • added std::function, not added bind as I'm not sure it really answers the question, while it does create a new functor its more about partially applying a functor, no? – jk. Oct 7 '13 at 22:00
  • 2
    Also: pointers to non-static member functions. – Kaz Oct 7 '13 at 22:25
  • 1
    @jk. : bind will partially apply functors, yes, but also many other callable things. Including those pointers to non-static member functions, which need an object. – MSalters Oct 7 '13 at 23:00
3

Here is one example where use of member function pointer - within a class, as an implementation detail - is perfectly acceptable, if one works with performance-sensitive code for different CPU architectures.

See the C++ FAQs for the proper use of member function pointer. It requires a different syntax than static function pointers.

(Thanks for Kaz for the suggestion.)

class SomePerformanceCriticalOperation
{
private:
    // the type declaration of a member function pointer

    typedef int (SomePerformanceCriticalOperation::*ProcessPtr)(size_t bytesToProcess, void* dataPtr);

    // the instance of a member function pointer, to be assigned to a member function
    // (inside the constructor)
    ProcessPtr m_ptr;

public:
    SomePerformanceCriticalOperation()
    {
        cpu_features feat = ::GetCpuFeatures();
        if (TestBit(feat, cpu_features_SSE41))
            m_ptr = &SomePerformanceCriticalOperation::Process_SSE41;
        else if (TestBit(feat, cpu_features_SSSE3))
            m_ptr = &SomePerformanceCriticalOperation::Process_SSSE3;
        else if (TestBit(feat, cpu_features_SSE3))
            m_ptr = &SomePerformanceCriticalOperation::Process_SSE3;
        else if (TestBit(feat, cpu_features_SSE2))
            m_ptr = &SomePerformanceCriticalOperation::Process_SSE2;
        else if (TestBit(feat, cpu_features_MMX))
            m_ptr = &SomePerformanceCriticalOperation::Process_MMX;
        else 
            m_ptr = &SomePerformanceCriticalOperation::Process_CPlusPlus;
    }

    // The CPU-specific functions, as usual. (Omitted.)

    int Process_SSE41(size_t bytesToProcess, void* dataPtr) { ... }
};
1

Certainly C programmers used to use function pointers a lot, but most of those uses have been surpassed with OO alternatives - though they might not be obvious without examining the problem being solved rather than the solution itself. For example, they were popular in implementing state machines but a C++ programmer would prefer to use a factory pattern.

One concept they are still necessary for is implementing a delegate (possibly the only reason to use one in the 21st century!?). Provided as part of the language in other places the poor c++ developer still has to write his own - but it's fun to do (no!?) and you can find a description of how to do it here: Stack Overflow

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.