c++ 中对静态函数指针成员的未定义引用,我做错了什么?

发布于 2024-12-10 18:39:58 字数 912 浏览 1 评论 0原文

请考虑这些文件:

ph:

#ifndef _p_h_
#define _p_h_

class p{
public:    
    static void set_func(int(*)());

private:
    static int (*sf)();

};
#endif

p.cpp:

#include "p.h"
#include <cstdio>

int (p::*sf)() = NULL;    //defining the function pointer

void p::set_func(int(*f)()){
    sf = f;
}

main.cpp:

#include "p.h"
#include <iostream>

int function_x(){
        std::cout << "I'm function_x()" << std::endl;
        return 1234;
}

int main(){
        p::set_func(function_x);
}

编译时,我得到这个:

$ g++ -o pp main.cpp p.cpp
/tmp/ccIs0M7r.o:p.cpp:(.text+0x7): undefined reference to `p::sf'
collect2: ld returned 1 exit status

但是:

$ g++ -c -o pp p.cpp

编译正确。

代码有什么问题吗?我只是找不到问题出在哪里,请您的帮助将不胜感激。

谢谢。

please consider these files:

p.h:

#ifndef _p_h_
#define _p_h_

class p{
public:    
    static void set_func(int(*)());

private:
    static int (*sf)();

};
#endif

p.cpp:

#include "p.h"
#include <cstdio>

int (p::*sf)() = NULL;    //defining the function pointer

void p::set_func(int(*f)()){
    sf = f;
}

main.cpp:

#include "p.h"
#include <iostream>

int function_x(){
        std::cout << "I'm function_x()" << std::endl;
        return 1234;
}

int main(){
        p::set_func(function_x);
}

when compiling, I get this:

$ g++ -o pp main.cpp p.cpp
/tmp/ccIs0M7r.o:p.cpp:(.text+0x7): undefined reference to `p::sf'
collect2: ld returned 1 exit status

but:

$ g++ -c -o pp p.cpp

compiles right.

What's wrong with the code? I just can't find where the problem is, please your help will be more than appreciated.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

滿滿的愛 2024-12-17 18:39:58

您尝试定义 p::sf 是不正确的 - 您的定义是一个名为 sf 的全局变量,其类型为 int (p::*)( ),即指向成员函数的指针。因此,p::sf 仍然未定义,因此出现链接器错误。

试试这个:

int (*p::sf)() = 0;

// or,

typedef int (*p_sf_t)();
p_sf_t p::sf = 0;

Your attempt at defining p::sf is incorrect – yours is a definition of a global variable named sf that is of type int (p::*)(), i.e. a pointer to a member function. Consequently p::sf remains undefined, hence the linker error.

Try this instead:

int (*p::sf)() = 0;

// or,

typedef int (*p_sf_t)();
p_sf_t p::sf = 0;
送你一个梦 2024-12-17 18:39:58

区别在于,错误仅在实际链接程序时发生。问题出在静态函数指针的声明中。正确的语法是:

int (*p::sf)() = NULL;    //defining the function pointer

The difference is because error only occurs when you actually link the program. The problem is in your declaration of the static function pointer. The correct syntax is:

int (*p::sf)() = NULL;    //defining the function pointer
娇妻 2024-12-17 18:39:58

您定义的是成员函数指针而不是函数指针。我不确定正确的语法是什么,但我会尝试这样的事情:

int (*p::sf)() = NULL; 

You define a member function pointer and not a function pointer. I'm not sure what the correct syntax is, but I would have tried something like this:

int (*p::sf)() = NULL; 
妥活 2024-12-17 18:39:58

我不会给出另一个答案(ildjarn 答案是正确的),但我会建议您使用另一种方法来实现相同的目标,而无需静态初始化(及其隐含的负担),

class p{
public:  
    typedef int (*func_t)();  
    static void set_func(func_t v) { 
      func_t& f = getFuncRef();
      f = v;
    }

    static void call_func() {
      func_t& f = getFuncRef();
      assert( f != 0);
      f();
    }

private:

    static func_t& getFuncRef() {
     static func_t sf = 0;
     return sf;
    }

};

这样您就可以将静态初始化委托给静态函数变量,这不会不存在影响静态数据变量的初始化顺序问题,并且是延迟初始化的

I will not give another answer (ildjarn answer is correct) but i will suggest you another way of achieving the same without static initialization (and the burdens it implies)

class p{
public:  
    typedef int (*func_t)();  
    static void set_func(func_t v) { 
      func_t& f = getFuncRef();
      f = v;
    }

    static void call_func() {
      func_t& f = getFuncRef();
      assert( f != 0);
      f();
    }

private:

    static func_t& getFuncRef() {
     static func_t sf = 0;
     return sf;
    }

};

in this way you delegate the static initialization to a static function variable, which doesn't have the initialization order problems that affect static data variables, and is lazy-initialised

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文