C++函数指针和类

C++ - function pointers and class

本文关键字:指针 函数 C++      更新时间:2023-10-16

当我试图编译这段代码以使用C++中的类来实现函数指针的概念时:

#include <iostream>
using namespace std;
class sorting
{
public:
void bubble_sort(int *arr, int size, bool (*compare)(int,int))
{
    int i,j,temp = 0;
    for(i = 0; i < size - 1; i++)
    {
        for(j = i+1; j < size; j++)
        {
            if(compare(arr[i],arr[j]))
            {
                temp = arr[i];
                arr[i] = arr[j];
                arr[j]  = temp;
            }
        }
    }
}
bool ascending(int x,int y)
{
    return x > y;
}
bool descending(int x,int y)
{
    return x < y;
}
void display(int *arr,int size)
{
    for(int index = 0; index < size; index++)
    {
        cout<<"arr["<<index<<"]:"<<arr[index]<<endl;
    }
}
};
int main()
{
    int arr[10] = {99,77,22,33,88,55,44,66,11,100};
    sorting s;
    cout<<"Ascending order"<<endl;
    s.bubble_sort(arr,10,&sorting::ascending);
    s.display(arr,10);
    cout<<"Descending order"<<endl;
    s.bubble_sort(arr,10,&sorting::descending);
    s.display(arr,10);
    return 0;
}

我在这些行中有错误:

s.bubble_sort(arr,10,&sorting::ascending);
s.bubble_sort(arr,10,&sorting::descending);

错误为:

error C2664: 'sorting::bubble_sort' : cannot convert parameter 3 from 'bool (__thiscall sorting::* )(int,int)' to 'bool (__cdecl *)(int,int)'

两条线路。有人能帮我消除这些错误吗?

ascendingdescending是成员函数,因此它们只能在sorting类成员上调用(实际上有三个参数,而不是两个)。

使它们成为static函数,或者更好的是,将sortingclass更改为namespace:它没有理由是一个类。

最简单的方法是使ascendingdescending静态函数的定义在类定义内部或外部,或者将函数声明/定义移动到类的作用域之外:

static bool ascending(int x,int y)
{
    return x > y;
}
static bool descending(int x,int y)
{
    return x < y;
}

编译器使用__thiscall调用约定将类中定义的函数视为成员函数,而正常的C++函数指针默认使用__cdecl调用约定(可以手动修改)。将定义移动到类之外会自动为函数提供__cdecl修饰符。将函数标记为static也为它们提供了__cdecl修饰符。

sorting::ascendingsorting::descending应该声明为static,或者根本不声明为成员,因为它们不在*this实例上操作。这就是为什么知道函数应该是static(或非成员)。

如果不将它们声明为static,则成员函数指针的语法会有所不同,并且还需要一个伪实例来进行调用。

C++中的函数指针略有不同。与C不同,成员函数并不总是"全局"可访问的,除非使其成为static。当设置为static时,对于该类的任意数量的实例,函数只有一个地址位置。使用此方法的代码将是:

#include<iostream>
using namespace std;
class sorting
{
public:
void bubble_sort(int *arr, int size, bool (*compare)(int,int))
{
    int i,j,temp = 0;
    for(i = 0; i < size - 1; i++)
    {
        for(j = i+1; j < size; j++)
        {
            if(compare(arr[i],arr[j]))
            {
                temp = arr[i];
                arr[i] = arr[j];
                arr[j]  = temp;
            }
        }
    }
}
static bool ascending(int x,int y)
{
    return x > y;
}
static bool descending(int x,int y)
{
    return x < y;
}
void display(int *arr,int size)
{
    for(int index = 0; index < size; index++)
    {
        cout<<"arr["<<index<<"]:"<<arr[index]<<endl;
    }
}
};
int main()
{
    int arr[10] = {99,77,22,33,88,55,44,66,11,100};
    sorting s;
    cout<<"Ascending order"<<endl;
    s.bubble_sort(arr,10,&sorting::ascending);
    s.display(arr,10);
    cout<<"Descending order"<<endl;
    s.bubble_sort(arr,10,&sorting::descending);
    s.display(arr,10);
    return 0;
}

另一种相同的方法是使用.*->*关键字。它们与类的实例一起使用,以便调用它们的一个(非静态)成员函数。如果调用发生在另一个成员函数中,您可以使用this指针。请阅读此处了解更多详细信息。参考。然后您的代码将是:

#include<iostream>
using namespace std;
class sorting
{
public:
void bubble_sort(int *arr, int size, bool (sorting::*compare)(int,int))
{
    int i,j,temp = 0;
    for(i = 0; i < size - 1; i++)
    {
        for(j = i+1; j < size; j++)
        {
            if((this->*compare)(arr[i],arr[j]))
            {
                temp = arr[i];
                arr[i] = arr[j];
                arr[j]  = temp;
            }
        }
    }
}
bool ascending(int x,int y)
{
    return x > y;
}
bool descending(int x,int y)
{
    return x < y;
}
void display(int *arr,int size)
{
    for(int index = 0; index < size; index++)
    {
        cout<<"arr["<<index<<"]:"<<arr[index]<<endl;
    }
}
};
int main()
{
    int arr[10] = {99,77,22,33,88,55,44,66,11,100};
    sorting s;
    cout<<"Ascending order"<<endl;
    s.bubble_sort(arr,10,&sorting::ascending);
    s.display(arr,10);
    cout<<"Descending order"<<endl;
    s.bubble_sort(arr,10,&sorting::descending);
    s.display(arr,10);
    return 0;
}