【问题标题】:typedef function pointer that takes argument ClassName* before defining ClassName?在定义 ClassName 之前接受参数 ClassName* 的 typedef 函数指针?
【发布时间】:2011-07-01 03:34:20
【问题描述】:

我有以下情况:

typedef void (*F_POINTER)(ClassName*);

class ClassName {
    public:
        F_POINTER f;
}

发生这种情况是因为 ClassName 的实例需要将指针本身传递给客户端。但是,如果我按这个顺序写东西,我会抱怨 ClassName 没有声明,诸如此类。但是,如果我切换它们,当我在类中声明实例时,我会抱怨没有声明 F_POINTER。

所以也许我在这里遗漏了一些简单的东西,但是我该如何完成呢?

【问题讨论】:

  • F_POINTER 的返回类型是什么。

标签: c++ syntax g++ function-pointers typedef


【解决方案1】:

转发声明:

class ClassName;

typedef (*F_POINTER)(ClassName*);

class ClassName {
    public:
        F_POINTER f;
}

或更短:

typedef (*F_POINTER)(class ClassName*); // implicit declaration;

【讨论】:

    【解决方案2】:

    这似乎在 GCC 4.5.2 (mingw32) 下工作:

    typedef void (*F_POINTER)(class ClassName);
    class ClassName {};
    void f (ClassName) {}
    
    int main ()
    {
        F_POINTER x = f;
    }
    

    我不会相信我的生活是否是合法的 C++,甚至不相信其他人描述的指针版本。前向声明和指针并不能解决所有问题,例如,不可能声明抛出不完整类型指针的方法,您需要对此进行完整定义。这可能同样是非法的,只是被编译器接受了。

    【讨论】:

    • 声明不完整类类型的函数参数是完全合法的,即使在非指针的情况下也是如此:你上面对F_POINTER 的定义很好。
    【解决方案3】:

    转发声明ClassName。类型可能不完整,无法使用指向它的指针。

    class ClassName;
    typedef (*F_POINTER)(ClassName*);
    
    class ClassName { ... };
    

    或者,将typedef 移动到类中。还可以考虑使用boost::function/std::function 而不是函数指针。

    【讨论】:

      【解决方案4】:

      您可以转发声明为,

      class ClassName;
      typedef void (*F_POINTER)(ClassName*); // assume that return is `void`
      

      F_POINTER 之前,或者您可以使用template 技巧来避免每个class 出现此类麻烦:

      template<typename RETURN, typename ARGUMENT>
      struct FuncPtr {  typedef RETURN (*F_POINTER)(ARGUMENT); };
      

      Usage:

      class ClassName {
      public:
        FuncPtr<void,ClassName*>::F_POINTER f;
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-06
        • 2020-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-16
        • 1970-01-01
        相关资源
        最近更新 更多