C++ - 函数指针和类

3

当我试图编译这段用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)'

针对这两行代码,有人能帮我排除这些错误吗?


1
最简单的解决方案?将比较函数设为“静态”。然后跟我重复:指向函数的指针与指向成员函数的指针不是同一件事。 - Some programmer dude
1
最简单的解决方法是将ascendingdescending标记为static - Alan Stokes
4个回答

2

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

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


1
最简单的方法是将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 修饰符。

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

1

sorting::ascendingsorting::descending应该声明为static,或者根本不作为成员,因为它们不对*this实例进行操作。这就是你知道一个函数应该是static(或非成员)的原因。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接