成员函数的宏错误

时间:2010-11-26 11:30:20

标签: c++ c-preprocessor

我正在玩宏(不是)

#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 *)

据我所知,函数指针是等价的。我做错了什么?

3 个答案:

答案 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);}\