Неопределенная ссылка на статический член указателя функции в C ++, что я делаю не так? - PullRequest
6 голосов
/ 20 октября 2011

пожалуйста, рассмотрите эти файлы:

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

при компиляции я получаю это:

$ 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

правильно компилируется.

Что не так с кодом? Я просто не могу найти, в чем проблема, пожалуйста, ваша помощь будет более чем оценена.

Спасибо.

Ответы [ 4 ]

12 голосов
/ 20 октября 2011

Ваша попытка определить p::sf неверна & ndash; yours - это определение глобальной переменной с именем sf типа int (p::*)(), то есть указатель на функцию-член. Следовательно, p::sf остается неопределенным, следовательно, ошибка компоновщика.

Попробуйте вместо этого:

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

// or,

typedef int (*p_sf_t)();
p_sf_t p::sf = 0;
4 голосов
/ 20 октября 2011

Разница в том, что ошибка возникает только тогда, когда вы действительно связываете программу.Проблема в вашем объявлении статического указателя на функцию.Правильный синтаксис:

int (*p::sf)() = NULL;    //defining the function pointer
3 голосов
/ 20 октября 2011

Вы определяете указатель на функцию-член, а не указатель на функцию.Я не уверен, что правильный синтаксис, но я бы попробовал что-то вроде этого:

int (*p::sf)() = NULL; 
1 голос
/ 27 октября 2011

Я не буду давать другой ответ (ответ 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;
    }

};

таким способом, которым вы делегируетестатическая инициализация статической переменной функции, которая не имеет проблем порядка инициализации, которые влияют на статические переменные данных, и инициализируется ленивым

...