简体   繁体   English

C ++:非成员函数的定义/声明的位置

[英]C++: location of definition/declaration of non-member function

I have a class Myclass: 我有一个班级Myclass:

in Myclass.h file: 在Myclass.h文件中:

class{
private:
    int sd;
    int sd2;

public:
    void func(int sd, short op, void *ptr);

    void start();
};

in Myclass.cpp file: 在Myclass.cpp文件中:

void Myclass::start(){
     struct arg_t *arg = (struct arg_t *)malloc(sizeof(struct arg_t));
     ....
     event_set(ev, sd, EV_READ, call_func, arg ); //this is a library API, which trigger the callback of call_func(sd, op, arg);
}

void Myclass::func(int sd, short op, void *ptr)){
...
if(some_conditions){
     struct arg_t *arg = (struct arg_t *)malloc(sizeof(struct arg_t))
     .... 
     event_set(ev, sd2, EV_READ, call_func, arg );
     .....

}
...
}

in main.cpp 在main.cpp中

int main(){
   Myclass obj;
   ....
   obj.start();
   ....
}

in start(), the event_set need a function of void(*func)() type as argument,but func() is of void Myclass::(*func)() type, so I define a new function something like below (the codes are not correct, but just show what I expect): 在start()中,event_set需要一个void(*func)()类型的void(*func)()作为参数,而func()是void Myclass::(*func)()类型的,因此我定义了一个类似于下面的新函数(该代码不正确,只是显示我的期望):

void call_func(int sd, short op, void *ptr){
    Myclass::func(int sd, short op, void *ptr);
}

however, I'm at a loss where to delcare and define call_func() so that the Myclass::start() can use call_func as argument and call_func() can call Myclass::func() 但是,我无所适从,在delcare并定义call_func()以便Myclass::start()可以使用call_func作为参数,而call_func()可以调用Myclass::func()

This is a known problem. 这是一个已知的问题。 Since pointers to class members are not regular pointers, one can not use class member functions in naive callbacks, which expect a simple function pointer. 由于指向类成员的指针不是常规指针,因此不能在幼稚的回调中使用类成员函数,因为它们需要一种简单的函数指针。

A solution is to make a callback function static , often private , and call the corresponding class function using the callback argument. 一种解决方案是使回调函数为static ,通常为private ,然后使用callback参数调用相应的类函数。 In your case, it would look like following: 您的情况如下所示:

class C {
private:
    int sd;
    static void call_func(int sd, short op, void* ptr) {
        C* obj = static_cast<C*>(ptr);
        obj->func(sd, op);
    }


public:
    void func(int sd, short op);

    void start()  {
        event_set(ev, sd, EV_READ, &call_func, this);
    }
};

EDIT 编辑

Fixed messed up start() and func() . 修复混乱的start()func()

I'm at a loss where to delcare and define call_func() so that the Myclass::start() can use call_func as argument and call_func() can call Myclass::func() 我无所适从,在delcare并定义call_func()以便Myclass::start()可以使用call_func作为参数,而call_func()可以调用Myclass::func()

You can put this all in your Myclass.cpp file, above the definition of Myclass::start().` 您可以将所有内容放在Myclass :: start()定义上方的Myclass.cpp文件中。

#include <Myclass.h>

void call_func(int sd, short op, void *ptr){
    Myclass::func(int sd, short op, void *ptr);
}

void Myclass::start(){
     event_set(ev, sd, EV_READ, call_func, NULL ); //this is a library API, which trigger the callback of call_func(sd, op, NULL);
}

void Myclass::func(int sd, short op, void *ptr)){
...
...
}

One other thing, with callback functions, the void* ptr is how you can pass a pointer to some data that the callback function will use. 另一方面,对于回调函数, void* ptr是如何将指针传递给回调函数将使用的某些数据的方式。 If you don't need anything like that then you don't need to be calling a non-static member function as the callback and you could simplify things. 如果您不需要这样的东西,那么您就不需要调用非静态成员函数作为回调,并且可以简化事情。 But to call non-static member function the way you're describing, you need an object to call it on, and that's what you would pass as the void *ptr : 但是要按照您描述的方式调用非静态成员函数,您需要一个对象来调用它,这就是您将作为void *ptr传递的内容:

// Myclass.h
class Myclass {
private:
    int sd;

public:
    void func(int sd, short op); // no void*
    void start();
};


// Myclass.cpp
#include <Myclass.h>

void call_func(int sd, short op, void *ptr){
    assert(ptr != NULL);
    static_cast<Myclass *>(ptr)->func(int sd, short op); // cast data to 'this' pointer
}

void Myclass::start(){
     event_set(ev, sd, EV_READ, call_func, this ); // pass the 'this' pointer as data
}

void Myclass::func(int sd, short op)){
...
...
}

the last argument of event_set() is still needed to be used for a pointer to an additional structure, so it can't be this 的最后一个参数event_set()仍然需要被用于指针的额外的结构,所以它不能被this

You need to pass this somehow or you can't call a member function, so if you have another structure you need to think about how to pass both. 您需要以某种方式传递this否则您将无法调用成员函数,因此,如果您具有其他结构,则需要考虑如何传递两者。

Can the other structure or a pointer to it be a member of the object? 其他结构或指向它的指针可以成为对象的成员吗? If so, then do that and pass this as the void *ptr . 如果是这样,则执行此操作并将this作为void *ptr传递。

Another option is to define a struct just for passing the data through the callback: 另一个选择是定义一个仅用于通过回调传递数据的struct

struct callback_params {
  Myclass *c;
  other_struct *s;
};

But you have to create this callback_params struct somewhere where it will live long enough for the callback to be able to receive it, which can be tricky. 但是您必须在某个地方创建这个callback_params结构,该结构将存在足够长的时间,以便回调能够接收它,这可能会很棘手。

WRONG ANSWER!!!! 错误的答案!!!!

My old tablet didn't load the code sections of the question correctly and I miss important parts of the question... 我的旧平板电脑未正确加载问题的代码部分,并且我错过了问题的重要部分...
Leaving here just as sake of completeness - maybe this can be util for someone else 出于完整性考虑,离开这里-也许对其他人有用

SORRY 抱歉

I don't know the complete stuff that you're doing but in this cases, if i don't need interface with old code I will go for std::function for sure. 我不知道您正在做的全部工作,但是在这种情况下,如果我不需要使用旧代码的接口,那么我肯定会使用std::function

But if is absolutely needed the pointers stuff, I generally do: 但是,如果绝对需要使用指针,我通常会这样做:

  • Put a very ugly name in the function - So every one will know that this is a 'hack' and not a good thing. 在函数中添加一个非常丑陋的名称-因此每个人都将知道这是一个“ hack”,而不是一件好事。 ex: _func_call_wrapper_(...) 例如: _func_call_wrapper_(...)
  • Put into the top of .cpp file the definition with the appropriated comments and so on. 将带有相应注释的定义放入.cpp文件的顶部,依此类推。 ex: 例如:

//This is a wrapper neeeded for... void __func_call_wrappper_(..);

  • Finally in the bottom of the .cpp file I define the function, of course, with a lot of comments of why this is needed. 最后,在.cpp文件的底部,我当然定义了该函数,并附带了许多说明为什么需要此函数的注释。

Refs: ccpreference 参考: ccpreference

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM