本文介绍了如何使用函数指针访问成员函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题
假设我们有一个简单的类来对整数列表进行排序,

The Problem
Lets say that we have a simple class to sort a list of integers,

class Sorter {
public:
    Sorter() {}
    ~Sorter() {}

    enum class Algorithm { Bubble, Heap, Merge, Insertion };

    void SetVector(const std::vector<int>& vec) { mVector = vec; }

    void Sort(Algorithm algo)
    {
        void (Sorter:: * pfSort)() = nullptr;

        switch (algo)
        {
        case Sorter::Algorithm::Bubble:
            pfSort = &Sorter::BubbleSort;
            break;
        case Sorter::Algorithm::Heap:
            pfSort = &Sorter::HeapSort;
            break;
        case Sorter::Algorithm::Merge:
            pfSort = &Sorter::MergeSort;
            break;
        case Sorter::Algorithm::Insertion:
            pfSort = &Sorter::InsertionSort;
            break;
        default:
            std::cerr << "Invalid or Unsupported Sort Algorithm!";
            break;
        }

        (this->*(pfSort))();
    }

private:
    void BubbleSort() { ... }
    void HeapSort() { ... }
    void MergeSort() { ... }
    void InsertionSort() { ... }

private:
    std::vector<int> mVector;
};

如您所见,何时进行排序,我们要求使用一种特定的算法,并根据该算法将函数分配给函数指针,最后将其称为搜索.

As you can see when were going to sort, we ask for a specific algorithm to use, and depending on it, we assign the function to a function pointer which at the end, we call it to search.

但是问题是,为什么我们要这样调用函数指针:(this-> *(pfSort))(); 而不是这样: pfSort()?

But the question is, why do we call the function pointer like this: (this->*(pfSort))(); and not like this: pfSort()?

推荐答案

让我们看一下这个简单的示例,

Lets look at this simple example,

struct Greeting {
    void SayHello() { std::cout << "Hello!\n"; }

    void (Greeting::*pfHello)() = nullptr;
};

int main()
{
    Greeting g;

    // Lets assign the function pointer to the pfHello variable.
    g.pfHello = &Greeting::SayHello;

    // Now lets call it like a traditional function pointer.
    g.pfHello();    // Triggers an error!

    // Now lets call it by dereferencing it.
    (*g.pfHello)(); // Still triggers an error..

    // Okay lets call it just like g.SayHello() but by swapping the dereferenced pointer with SayHello.
    (g.*(g.pfHello))(); // Works fine!
}

通过查看示例,我们可以看到调用成员函数指针的唯一方法是通过提供解引用的函数指针作为函数主体(在本例中为 SayHello ).并且必须实例化该对象才能执行此操作,就像如果要直接调用 SayHello()方法那样,我们将如何执行该操作.

By looking at the example, we can see that the only way to call the member function pointer is by providing the dereferenced function pointer as the function body (in this case SayHello). And the object needs to be instantiated in order to do this, just like how we would do it if were going to call the SayHello() method directly.

为什么我们需要在调用对象之前实例化该对象?
这是因为为了使函数能够访问其他成员变量和成员函数,需要实例化该对象.对于静态函数来说,这将不是一个问题(因为它们无法访问成员变量和成员函数).

Why do we need to instantiate the object before calling it?
That's because in order for the function to access other member variables and member functions, the object needs to be instantiated. This wont be an issue for static functions (because they cant access member variables and member functions).

为什么已取消引用函数指针?
那是因为您没有直接存储函数指针.您存储的函数指针的地址( g.pfHello =& Greeting :: SayHello; ).这就是为什么我们需要取消引用它的原因.

Why dereferenced function pointer?
Well that's because your not directly storing the function pointer. Your storing the address of the function pointer (g.pfHello = &Greeting::SayHello;). This is why we need to dereference it.

这就是为什么我们必须使用以下代码:(this-> *(pfSort))(); 而不是以下代码: pfSort().

That's why we have to use this: (this->*(pfSort))(); instead of this: pfSort().

希望这会清除一些疑问!

Hope this would clear some doubts!

这篇关于如何使用函数指针访问成员函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 01:15