C++ 中指向成员函数的函数指针

Jay Shaw 2023年10月12日
  1. 在 C++ 中实现指向成员函数的函数指针
  2. 在 C++ 中附加指向成员函数的指针
  3. 在 C++ 中不使用指针符号调用指向成员函数的指针
  4. 在 C++ 中给出与函数指针相同的类的方法
  5. 在 C++ 中使用字符串命令指向成员函数的函数指针
C++ 中指向成员函数的函数指针

当使用编程语言创建变量时,机器必须将其值存储在计算机内存中。机器分配一些内存给这个变量,无论是否为空。

通常需要位置而不是变量的值。在此期间,可以通过指针获取这些值。

此外,与引用内存地址相比,C++ 中的指针还可用于指向一段代码,例如函数。这些被称为函数指针,提高了代码的效率。

本文的示例将清楚地展示如何在类中使用函数指针来使指针指向 C++ 中的成员函数。

在 C++ 中实现指向成员函数的函数指针

有两种方法可以做到这一点。

  1. 创建一个指向成员函数的函数指针。
  2. 仅使用函数指针的名称调用方法。

在 C++ 中附加指向成员函数的指针

使用指针函数需要以下步骤。

  1. 具有返回类型的参数化函数 - void。
  2. 类型转换指针变量。
  3. 将指针变量分配给方法。
  4. 使用指针调用主函数内部的参数化函数的方法调用。

为程序内部的输入/输出功能导入标准 stdio 包。函数 display 使用参数 var1 声明,具有整数数据类型。

void display(int var1) { printf("The variable holds value = %d\n", var1); }

display 方法中,会打印 var1

变量 ptr_method 在主函数中具有数据类型 void。必须注意的是,void 可以用作 c++ 中的数据类型,但它充当占位符,并不真正代表一种数据类型。

然后为声明的指针变量提供一个整数参数,如下所示:

void (*ptr_method)(int)

ptr_method 有一个整数参数。这将在调用 ptr_method 时将值传递给成员方法。

因为使用任何其他数据类型会导致编译器出现不正确的转换错误,所以指针函数 ptr_method 已被赋予 void 数据类型。

使用下面的语法将函数指针分配给程序开始时声明的函数。使用以下语法使指针指向函数 display

ptr_method = &display;

最后,使用提供为 "65" 的整数参数调用指针函数。

代码:

#include <stdio.h>

// This method has a parameter int and a return type which is void

void display(int var1) { printf("The variable holds value = %d\n", var1); }

int main() {
  void (*ptr_method)(int);
  ptr_method = &display;

  (*ptr_method)(65);

  return 0;
}

输出:

The variable holds value = 65

在 C++ 中不使用指针符号调用指向成员函数的指针

本例中使用的程序与上述程序相同,只是函数调用不同。这里,使用变量名调用指针变量,不包括星号 (*)。

该程序按预期工作,因为当函数指针指向一个方法时,可以使用指针和变量形式访问存储在其中的方法的内存地址。例如,当定义函数指针 ptr_method 时,函数 display 赋值是通过直接使用变量名来完成的,而不是像前面示例中那样在变量名前添加&

在函数调用时,直接调用函数指针 ptr_method,不使用指针符号(*)并传递值 54

void (*ptr_method)(int);
ptr_method = display;

ptr_method(54);

代码:

#include <stdio.h>

void display(int var1) { printf("The variable holds value = %d\n", var1); }

int main() {
  void (*ptr_method)(int);
  ptr_method = display;

  ptr_method(54);

  return 0;
}

输出:

The variable holds value = 54

在 C++ 中给出与函数指针相同的类的方法

本例中使用的程序与其他两个程序类似。但是在这里,指针是一种方法,而其他两个程序中的工作是由简单的指针变量处理的。

构造函数类 assgnPtr 由两个公共成员创建 - 一个 char 方法 foo 和另一个 char 方法,它是一个函数指针 ptr。这两种方法如下面的语法所示,从语法的最后一行可以清楚地看出,它指向函数指针的类 assgnPtr

public:
char foo();
char (assgnPtr::*ptr)();

在声明公共方法后,函数 foo() 提供了一个返回 f。这意味着当调用函数指针时,程序调用函数 foo 并打印返回的任何内容。

在 main 方法中声明了一个名为 var1 的变量。此变量用作类对象。

这是因为作为成员函数的函数指针具有在没有来自同一类的对象的情况下无法访问的缺点。成员函数按以下语法分配给指针变量。

int main() {
  assgnPtr var1;
  var1.ptr = &assgnPtr::foo;

指针 ptr 与对象类 var1 一起使用,并分配给方法 foo。作为构造函数,该方法必须使用::符号分配,表明该函数是类 assgnPrt 的成员方法。

最后,需要打印结果。

printf("%c\n", (var1.*(var1.ptr))());

它可能会让读者感到不安,因为它理解起来非常复杂。所以需要把它分解成小块才能清楚地理解。

var1.ptr 是指向类 assgnPtr 的成员函数的指针。但是当使用 *(var1.ptr) 时,它会变成指针引用,而打印 *(var1.ptr) 不能直接使用,因为 ptr 不在范围内。

出于这个原因,它需要与类对象 var1 绑定为 var1.*(var1.ptr)

最后,(var1.*(var1.ptr))() 调用不带参数的方法。print 语句打印使用函数指针调用方法时返回的值。

完整源代码:

#include <iostream>

class assgnPtr {
 public:
  char foo();
  char (assgnPtr::*ptr)();
};

char assgnPtr::foo() { return 'f'; }

int main() {
  assgnPtr var1;
  var1.ptr = &assgnPtr::foo;
  printf("%c\n", (var1.*(var1.ptr))());
}

输出:

f

在 C++ 中使用字符串命令指向成员函数的函数指针

在这个例子中,程序使用字符串命令来分配函数指针。核心概念类似,只是成员方法使用关系运算符来检查和分配指针。

该程序使用两个导入函数,用于 i/oiostream 和用于字符串命令的 string。创建了一个构造器类 assgnPtr2

有两个私有成员 displaypass_value 和一个公共成员 func_ptr,它将是函数指针。

私有成员 pass_value 具有三个参数 - 数据类型字符串的变量 x 和 y,以及函数原型 foo。函数原型声明参数 foo 将是一个指向函数的指针。

分配指针时,方法 display 将打印一条语句。方法 func_ptr 调用方法 pass_value 并将 xy 的值作为参数传递,并使用&符号作为函数原型的参数附加方法 display

最后,在方法 pass_value 中,使用关系运算符 == 比较传递的 x 和 y 的值。如果 x 和 y 的值都匹配,则 if 语句将指针 foo 分配给方法。

在 main 函数中,创建了一个类对象 var。使用这个对象,方法 func_ptr 被调用。

完整源代码:

#include <iostream>
#include <string>

class assgnPtr2 {
 public:
  void func_ptr();

 private:
  void display();
  void pass_value(std::string x, std::string y, void (assgnPtr2::*foo)());
};

void assgnPtr2::display() { std::cout << "Pointer Assigned\n"; }

void assgnPtr2::func_ptr() { pass_value("h", "h", &assgnPtr2::display); }

void assgnPtr2::pass_value(std::string x, std::string y,
                           void (assgnPtr2::*foo)()) {
  if (x == y) {
    (this->*foo)();
  }
}

int main() {
  assgnPtr2 var;
  var.func_ptr();
  return 0;
}

输出:

Pointer Assigned

相关文章 - C++ Pointer