我正在玩宏(不是)
#include <iostream>
using namespace std;
#define DEF_ATTRIBUTE(type, name) type name;\
typedef void (*type_name_t)(CLASS_NAME*);\
type_name_t ptr_type_name;\
void type_name(){( ptr_type_name = &CLASS_NAME::type_name);}\
class Test
{
public:
#define CLASS_NAME Test
DEF_ATTRIBUTE(int, i_Test);
void Print()
{
cout << "Test::Print()" << endl;
}
};
int main()
{
Test t;
t.Print();
}
扩展为:
class Test
{
public:
int i_Test; typedef void (*type_name_t)(Test*); type_name_t ptr_type_name; void type_name(){( ptr_type_name = &Test::type_name);};
void Print()
{
cout << "Test::Print()" << endl;
}
};
并产生编译器错误:
main.cpp:在成员函数void Test :: type_name()中:
main.cpp:16:错误:无法在赋值中将void(Test :: )()转换为void()(Test *)
据我所知,函数指针是等价的。我做错了什么?
答案 0 :(得分:4)
指针类型不等价:type_name_t
是函数指针(指向自由函数的指针),而&Test::type_name
是指向成员函数的指针。这就是编译器告诉你的。
无法将指向成员函数的指针转换为简单函数指针的原因是(非静态)成员函数具有隐藏的this
参数。您无法通过普通函数指针调用成员函数,因为无法传递this
参数。您试图通过提供type_name_t
CLASS_NAME*
参数来解决这个问题 - 从概念上讲,这是正确的做法,但C ++不会这样做。
相反,您需要做的是将type_name_t
作为指向成员函数的指针:
typedef void (CLASS_NAME::*type_name_t)();
(未经测试。我希望语法是正确的;我不会每天使用指向成员函数的指针。)
答案 1 :(得分:2)
函数指针不等效。
void (*type_name_t)(Test*)
与
不同&Test::type_name
您的函数指针的类型是:指向一个带有一个参数的函数的指针,一个Test指针,并且不返回任何值。
你想要的是一个指向成员的指针函数,具体来说,是一个指向成员函数的指针,它不带任何参数并且不返回任何值:
void (Test::*type_name_t) (); // note the empty parameter list!
答案 2 :(得分:1)
类型不同。
&Test::type_name
是指向类Test
的成员函数的指针,而type_name_t
不能保存类Test
的任何成员函数的地址。它只是一个指向自由函数的指针(而不是成员函数)。
试试这个:
#define CLASS_NAME Test
#define DEF_ATTRIBUTE(type, name) type name;\
typedef void (CLASS_NAME::*type_name_t)();\
type_name_t ptr_type_name;\
void type_name(){( ptr_type_name = &CLASS_NAME::type_name);}\