【问题标题】:How to use function pointers to access member functions?如何使用函数指针访问成员函数?
【发布时间】:2021-01-15 09:18:21
【问题描述】:

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

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

正如您所看到的,何时进行排序,我们要求使用特定的算法,并根据它,将函数分配给函数指针,最后我们将其称为搜索。

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

【问题讨论】:

  • 这不是一个函数指针,它是一个成员函数指针,虽然很高兴你已经投入工作来回答这个问题,但这个问题已经以多种形式得到了回答,例如thisthis.

标签: c++ function-pointers


【解决方案1】:

如何使用函数指针访问成员函数?

没有办法直接这样做,因为函数指针只能指向函数;不要(非静态)成员函数。

相反,您可以使用成员函数指针 - 您在示例中确实使用过。

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

因为它不是函数指针。它是一个成员函数指针。调用(非静态)成员函数的语法是这样的,因为必须传递实例参数——在这种情况下是*this

【讨论】:

    【解决方案2】:

    让我们看看这个简单的例子,

    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() 方法一样。

    为什么我们需要在调用对象之前实例化它?
    那是因为为了让函数访问其他成员变量和成员函数,对象需要被实例化。这不会是静态函数的问题(因为它们无法访问成员变量和成员函数)。

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

    这就是为什么我们必须使用这个:(this-&gt;*(pfSort))(); 而不是这个:pfSort()

    希望这能消除一些疑虑!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 1970-01-01
      • 2013-10-13
      • 1970-01-01
      • 2011-07-10
      相关资源
      最近更新 更多