简体   繁体   English

C++ function 指针

[英]C++ function pointers

I'm experimenting with c++ as an excerise.我正在尝试使用 c++ 作为练习。 I'm implementing a template class "MioVettore" that implements different reordering algorithms.我正在实现一个模板 class “MioVettore”,它实现了不同的重新排序算法。

I'm implementing ShellSort and I want to be able to tell what kind of numerical series to use.我正在实现 ShellSort,我希望能够知道使用什么样的数字系列。 To do that I thought it was a good a idea to assign a different function to a function pointer depending on the option selected by the user.为此,我认为根据用户选择的选项将不同的 function 分配给 function 指针是个好主意。

template <class T>
class MioVettore
{
private :
    std::vector<T> data;

    int SerieKnuth(const int &h) {
        return h * 3 + 1;
    }
    int SerieSequenza(const int& h) {
        return 0;
    }
    int SerieSedgewick(const int& h) {
        return 0;
    }

public:
    MioVettore() {};

    enum SerieType { KNUTH, SEQUENZA, SEDGEWICK };

    void ShellSort(SerieType t) {

        int (*evaluateH) (const int&);

        switch ((int)t)
        {

        case (int)KNUTH:
            evaluateH = SerieKnuth;
            break;

        case (int)SEDGEWICK:
            evaluateH = SerieSedgewick;
            break;

        case (int)SEQUENZA:
            evaluateH = &SerieSequenza;
            break;

        default:
            std::cout << "valore serie non riconosciuto" << std::endl;
            return;
    }

    /* ... */
}

When I try to assign a function to evaluateH I got some errors that I have a hard time understanding, like:当我尝试分配 function 来evaluateH时,我遇到了一些我很难理解的错误,例如:

'operator' : illegal operation on bound member function expression
The compiler found a problem with the syntax to create a pointer-to-member.

As I know a function pointer is defined as,据我所知,function 指针定义为,

int f(int a) {return a;}

int (*pf) (int) = f;

So I can't understand where is the error.所以我不明白错误在哪里。

There are two ways to approach this issue.有两种方法可以解决这个问题。

  1. State that the member variables are static . State ,成员变量为static
  2. Say where the function pointers are pointed to (to which class).说出 function 指针指向的位置(指向哪个类)。

For the first option,对于第一个选项,
When looking at the three functions, we can see that it doesn't do anything/ doesn't have anything to do with the member variables.查看这三个函数时,我们可以看到它什么都不做/与成员变量没有任何关系。 It performs calculations using the arguments.它使用 arguments 执行计算。 This means that specifying it as static wouldn't be an issue and this is how it would look like,这意味着将其指定为static不会成为问题,这就是它的样子,

template <class T>
class MioVettore
{
private:
    std::vector<T> data;

    static int SerieKnuth(const int& h) {
        return h * 3 + 1;
    }
    static int SerieSequenza(const int& h) {
        return 0;
    }
    static int SerieSedgewick(const int& h) {
        return 0;
    }

public:
    MioVettore() {};

    enum SerieType { KNUTH, SEQUENZA, SEDGEWICK };

    void ShellSort(SerieType t) {

        int (*evaluateH) (const int&);

        switch (t)
        {

        case KNUTH:
            evaluateH = SerieKnuth;
            break;

        case SEDGEWICK:
            evaluateH = SerieSedgewick;
            break;

        case SEQUENZA:
            evaluateH = SerieSequenza;
            break;

        default:
            std::cout << "valore serie non riconosciuto" << std::endl;
            return;
        }

        /* ... */
    }
};

For the second option,对于第二个选项,
We can specify where to take the function pointer from, or in other words, which class contains the function pointers.我们可以指定从哪里获取 function 指针,或者换句话说,哪个 class 包含 function 指针。 This is how you can implement this.这就是你可以实现的方式。

template <class T>
class MioVettore
{
private:
    std::vector<T> data;

    int SerieKnuth(const int& h) {
        return h * 3 + 1;
    }
    int SerieSequenza(const int& h) {
        return 0;
    }
    int SerieSedgewick(const int& h) {
        return 0;
    }

public:
    MioVettore() {};

    enum SerieType { KNUTH, SEQUENZA, SEDGEWICK };

    void ShellSort(SerieType t) {

        int (MioVettore<T>::*evaluateH) (const int&);

        switch (t)
        {

        case KNUTH:
            evaluateH = &MioVettore<T>::SerieKnuth;
            break;

        case SEDGEWICK:
            evaluateH = &MioVettore<T>::SerieSedgewick;
            break;

        case SEQUENZA:
            evaluateH = &MioVettore<T>::SerieSequenza;
            break;

        default:
            std::cout << "valore serie non riconosciuto" << std::endl;
            return;
        }

        // This is how to call it.
        (this->*(evaluateH))(1);

        /* ... */
    }
};

This advantage of using this over the other is that we can access member variables from the member functions which we cant do if we specify the functions as static .使用此方法的优点是我们可以从成员函数中访问成员变量,如果我们将函数指定为static ,我们将无法做到这一点。

Note: You don't have to say (int)t and (int)SEDGEWICK in the switch and case statements as the compiler does that implicitly.注意:您不必在switchcase语句中说(int)t(int)SEDGEWICK ,因为编译器会隐式执行此操作。 enum s are basically integer constants which has a name to make it easier for developers to group them. enum基本上是 integer 常量,其名称便于开发人员对它们进行分组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM