首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++错误:必须调用对非静态成员函数的引用

C++错误:必须调用对非静态成员函数的引用
EN

Stack Overflow用户
提问于 2014-11-13 02:35:39
回答 2查看 20.6K关注 0票数 5

我正在尝试创建一个类来抽象libuv网络函数的一些基本行为。

代码语言:javascript
运行
复制
#define TCP_BACKLOG 256
class _tcp {
    uv_tcp_t* tcp = NULL;
    public:
    ~_tcp() { delete tcp; }
    void listen_uv_listen_uv_connection_cb(uv_stream_t* stream, int status) {
        printf("NEW CONNECTION\n");
    }
    void listen(const char* host, int port) {
        tcp = new uv_tcp_t();
        uv_tcp_init(uv_default_loop(), tcp);
        sockaddr_in* addr = new sockaddr_in();
        uv_ip4_addr(host, port, addr);
        uv_tcp_bind(tcp, (const sockaddr*)addr, 0);
        delete addr;

        uv_listen((uv_stream_t*)tcp, TCP_BACKLOG, listen_uv_listen_uv_connection_cb);
    }
};

前面显示的代码的问题是,当我试图编译它时,我得到了以下错误:

代码语言:javascript
运行
复制
error: reference to non-static member function must be called
  on: uv_listen((uv_stream_t*)tcp, TCP_BACKLOG, listen_uv_listen_uv_connection_cb);
                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

它指出listen_uv_listen_uv_connection_cb是罪魁祸首。

有人能向我解释一下,为什么这是一个错误,我应该如何修复它?

uv_listen()uv_connection_cb签名声明如下

代码语言:javascript
运行
复制
UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
typedef void (*uv_connection_cb)(uv_stream_t* server, int status);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-13 02:52:45

即使具有相同的签名,也不能将非静态成员函数转换为指向函数的指针,因为从技术上讲,成员函数有一个名为this的隐藏参数。其中一种解决方案是使listen_uv_listen_uv_connection_cb成为静态的:

代码语言:javascript
运行
复制
class _tcp {
    uv_tcp_t* tcp = NULL;
    public:
    ~_tcp() { delete tcp; }
    static void listen_uv_listen_uv_connection_cb(uv_stream_t* stream, int status) {
        printf("NEW CONNECTION\n");
    }
    void listen(const char* host, int port) {
        tcp = new uv_tcp_t();
        uv_tcp_init(uv_default_loop(), tcp);
        sockaddr_in* addr = new sockaddr_in();
        uv_ip4_addr(host, port, addr);
        uv_tcp_bind(tcp, (const sockaddr*)addr, 0);
        delete addr;

        uv_listen((uv_stream_t*)tcp, TCP_BACKLOG, 
                   &_tcp::listen_uv_listen_uv_connection_cb);
    }
};

为了能够调用非静态方法,您需要一种从"uv_stream_t* _tcp“参数获取指向流实例的指针的方法。我建议使用此文档http://docs.libuv.org/en/latest/handle.html#c.uv_handle_t中的"void* uv_handle_t.data“指针

代码语言:javascript
运行
复制
static void listen_uv_listen_uv_connection_cb(uv_stream_t* stream, int status) {
    _tcp *tcp = static_cast<_tcp *>( stream->data );
    tcp->regularMethod();
}

当然,您应该在初始化uv_tcp_t *时将this指针赋值给uv_handle_t.data

代码语言:javascript
运行
复制
void listen(const char* host, int port) {
    tcp = new uv_tcp_t();
    uv_tcp_init(uv_default_loop(), tcp);
    tcp->data = this; // do not forget it
    ...
}

我会把这个初始化代码移到构造器中。

在这个库中使用的每个回调都需要这样的静态包装器。对于c++11,您可能可以使用lambda。

票数 11
EN

Stack Overflow用户

发布于 2014-11-13 02:37:48

代码语言:javascript
运行
复制
void listen_uv_listen_uv_connection_cb(uv_stream_t* stream, int status) {
        printf("NEW CONNECTION\n");
    };        <<<<<remove ;

函数定义的末尾不能有分号。

你应该为这个类编写构造函数/复制ctr/赋值运算符。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26894063

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档