我正在尝试将 C 代码移植到 C++ 程序,从而将 C 程序的逻辑封装在 C++ 类中。我遇到的步骤是使用函数指针(结构数据成员内部的字段)来调用成员函数。
我尝试从头文件、源文件和驱动程序文件中仅提取涉及的代码:
C++ 头如下所示:
#include <array>
#include <cstdint>
class MY_CLASS {
public :
// 1. within-class definition of the function pointer type :
typedef uint8_t * ( MY_CLASS :: * func_ptr_type ) ( uint8_t in_uint8 ) ;
// 2. within-class definition of the struct type :
typedef struct _struct_with_func_ptr {
func_ptr_type func_ptr_member ;
} struct_with_func_ptr_type ;
// 3. declaration of a data member of the struct type :
struct_with_func_ptr_type struct_with_func_ptr_data_member ;
// 4. declaration of the member function to be assigned to the function pointer of the struct data member :
uint8_t * func_to_be_assigned_to_func_ptr ( uint8_t in_uint8 ) ;
// 5. array as data member to be accessed by the member function, assigned to the function pointer of the struct data member :
std :: array < uint8_t, 5 > array_data_member ;
// 6. declaration of the member function to make use of the function pointer of the struct data member :
void func_to_make_use_of_func_ptr ( uint8_t in_uint8 ) ;
// 7. Constructor declaration :
MY_CLASS () ;
} ;
extern MY_CLASS my_object ;
最初在C程序中函数指针的定义看起来是这样的:
typedef uint8_t * ( * func_ptr_type ) ( uint8_t in_uint8 ) ;
但是只要我从在线链接中理解,我需要一个指向成员函数的指针而不是常规的C函数指针,例如https://web.archive.org/web/20120723071248/http://www.dulcineatech.com/tips/code/c++/member-pointers.html
我的 C++ 源代码如下:
#include <iostream>
#include "my_header.hpp"
MY_CLASS :: MY_CLASS () :
array_data_member {}
{} ;
uint8_t * MY_CLASS :: func_to_be_assigned_to_func_ptr ( uint8_t in_uint8 ) {
return & array_data_member [ in_uint8 ] ;
}
void MY_CLASS :: func_to_make_use_of_func_ptr ( uint8_t in_uint8 ) {
// 1st attempt :
uint8_t * ptr_to_uint8_t = struct_with_func_ptr_data_member . func_ptr_member ( in_uint8 ) ;
// error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((MY_CLASS*)this)->MY_CLASS::struct_with_func_ptr_data_member.MY_CLASS::_struct_with_func_ptr::func_ptr_member (...)’, e.g. ‘(... ->* ((MY_CLASS*)this)->MY_CLASS::struct_with_func_ptr_data_member.MY_CLASS::_struct_with_func_ptr::func_ptr_member) (...)’
// 2nd attempt :
// uint8_t * ptr_to_uint8_t = struct_with_func_ptr_data_member .* func_ptr_member ( in_uint8 ) ;
// error: ‘func_ptr_member’ was not declared in this scope; did you mean ‘func_ptr_type’?
// 3rd attempt :
// ( ( MY_CLASS * ) this ) -> MY_CLASS :: struct_with_func_ptr_data_member . MY_CLASS :: _struct_with_func_ptr :: func_ptr_member ( in_uint8 ) ;
// error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((MY_CLASS*)this)->MY_CLASS::struct_with_func_ptr_data_member.MY_CLASS::_struct_with_func_ptr::func_ptr_member (...)’, e.g. ‘(... ->* ((MY_CLASS*)this)->MY_CLASS::struct_with_func_ptr_data_member.MY_CLASS::_struct_with_func_ptr::func_ptr_member) (...)’
// 4th attempt :
// ( ( MY_CLASS * ) this ) -> MY_CLASS :: struct_with_func_ptr_data_member .* MY_CLASS :: _struct_with_func_ptr :: func_ptr_member ( in_uint8 ) ;
// error: invalid use of non-static data member ‘MY_CLASS::_struct_with_func_ptr::func_ptr_member’
std :: cout << "data member array value @ index " << unsigned ( in_uint8 ) << " = " << unsigned ( * ptr_to_uint8_t ) << std :: endl ;
}
MY_CLASS my_object ;
我的主要功能驱动程序代码如下所示:
#include <iostream>
#include <cstdint>
#include "my_header.hpp"
int main () {
// my_object . struct_with_func_ptr_data_member . func_ptr_member = my_object . func_to_be_assigned_to_func_ptr ;
// error: cannot convert ‘uint8_t* (MY_CLASS::*)(uint8_t)’ {aka ‘unsigned char* (MY_CLASS::*)(unsigned char)’} to ‘MY_CLASS::func_ptr_type’ {aka ‘unsigned char* (*)(unsigned char)’} in assignment
// due to function pointer type definition, i.e. typedef uint8_t * ( * func_ptr_type ) ( uint8_t in_uint8 ) ;
// modifying the function pointer type definition solves the error, i.e. typedef uint8_t * ( MY_CLASS :: * func_ptr_type ) ( uint8_t in_uint8 ) ;
my_object . struct_with_func_ptr_data_member . func_ptr_member = & MY_CLASS :: func_to_be_assigned_to_func_ptr ;
// this seems to be acceptable for the compiler
my_object . func_to_make_use_of_func_ptr ( 2 ) ;
}
由于在尝试使用结构体数据成员中的函数指针成员调用相应的成员函数时出现错误,我无法编译 C++ 程序。
正确的做法是什么?
对于任何对成员指针的调用,由于运算符优先级
,您始终需要在“函数指针”部分周围添加额外的括号(this->*struct_with_func_ptr_data_member.func_ptr_member)(in_uint8);
// or with extra brackes so that people don't have to look up precedence table even more
(this->*(struct_with_func_ptr_data_member.func_ptr_member))(in_uint8);
如果真的必须这么复杂,我宁愿用额外的变量来简化它:
const auto func_ptr = struct_with_func_ptr_data_member.func_ptr_member;
uint8_t* ptr_to_uint8_t = (this->*func_ptr)(in_uint8);