代码之家  ›  专栏  ›  技术社区  ›  nakiya

具有成员函数的宏错误

  •  2
  • nakiya  · 技术社区  · 14 年前

    我在玩宏(不是)

    #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::键入_name():
    main.cpp:16:错误:无法转换void(测试: )(一)无效( )(测试*)分配中

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

    3 回复  |  直到 8 年前
        1
  •  2
  •   Skizz    14 年前

    函数指针不等价。

    void (*type_name_t)(Test*)
    

    &Test::type_name
    

    函数指针的类型是:指向函数的指针,该函数接受一个参数、一个测试指针,并且不返回任何值。

    您需要的是指向成员函数的指针,特别是指向不带参数且不返回值的成员函数的指针:

    void (Test::*type_name_t) (); // note the empty parameter list!
    
        2
  •  4
  •   Martin B    14 年前

    指针类型不等价:A type_name_t 是函数指针(指向自由函数的指针),而 &Test::type_name 是指向成员函数的指针。这就是编译器告诉你的。

    无法将指向成员函数的指针转换为简单函数指针的原因是(非静态)成员函数具有隐藏的 this 参数。不能通过纯函数指针调用成员函数,因为无法传递 参数。你想用你的 键入名称 CLASS_NAME* 参数——在概念上是正确的事情,但是C++不是这样工作的。

    相反,你需要做的是 键入名称 作为指向成员函数的指针:

    typedef void (CLASS_NAME::*type_name_t)();
    

    (未经测试。我希望语法正确;我不会每天都使用指向成员函数的指针。)

        3
  •  1
  •   Prasoon Saurav    14 年前

    类型不同。

    &Test::type_name 是指向类的成员函数的指针 Test 鉴于 type_name_t 无法保存类的任何成员函数的地址 测试 . 它只是指向自由函数(而不是成员函数)的指针。

    试试这个:

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