8

我经常使用前向类声明和指向这些类的指针。

我现在需要通过多个层传递函数指针。我宁愿将声明我的函数指针原型的标头仅包含在取消引用函数指针的模块中,而不是包含在简单地传递该指针值的每个层中。

这可能吗?

=====

从回复中我怀疑我没有足够清楚地表达问题。我寻求类似于前向类声明的类比。我们都同意我可以写:

类 foo;

空栏(foo*);

无效 waz(foo* p) { bar(p); }

请注意,除了名称之外,waz 对 foo 类一无所知。也许 bar 可以访问 foo 的完整描述。也许 bar 会简单地将 p 传递得更远。谁在乎?只有那些取消引用 foo* 的网站。所有其他站点只需要“class foo;”。

同样,我知道我可以写:

typedef void foo(int, double);

空栏(foo*);

无效 waz(foo* p) { bar(p); }

不同之处在于,现在标识符 foo 不仅已知表示函数类型,而且还带有完整的签名/原型。这迫使我进入两种不愉快的情况之一:

1)在多个站点克隆 typedef(糟糕!脆弱!) 2)将 typedef 粘贴在标头中,并将其包含在提到 foo* 的任何地方。

注意不对称:在数据对象的情况下,我只需要在我想取消引用 foo* 的那些点提供类 foo 的完整描述;在函数的情况下,我需要在任何我想提到 foo* 的地方提供完整的签名/原型。

那么有没有办法弥补这种不对称性呢?

4

6 回答 6

4

您可以使用未定义的结构类型来执行此操作,但代价是额外的取消引用。

把它放在主头文件中:

typedef struct FuncStruct *FuncPtr;

这声明struct FuncStruct但不声明任何字段,然后它声明了一个指向该结构的指针,称为FuncPtr. 您可以传递FuncPtrs 但不能取消引用它们。

然后在特定文件(或更具体的 .h 文件)中,您实际上可以定义struct FuncStruct如下:

struct FuncStruct {
  int (*f)(int, char, double);
};

然后通过此定义的代码可以取消引用 aFuncPtr以获取实际的函数指针。

请注意,这是对强制转换的额外取消引用,这意味着您需要对FuncStructs 进行一些内存管理。

于 2010-04-04T03:30:52.980 回答
3

对于传递函数指针,您只需要知道参数类型和返回类型:

void f(void (*func)(int));

这里,f()是一个函数,它接受一个函数指针,指向一个接受int并返回的函数void

typedefs 使其更具可读性:

typedef void (*FuncPtr)(int);
void f(FuncPtr func);

一般来说,您可能想查看仿函数或使用例如Boost.FunctionBoost.Bind。这样你也可以传入绑定的成员函数或函数对象:

void f(boost::function<void (int)> fn) {
    fn(42);
}

struct X {
    void f(int) {}
};

// ...
X x;
f(boost::bind(&X::f, &x, _1));
于 2010-04-04T03:19:43.753 回答
0

当然,例如

typedef void (*FOOFUNC)(int x, int y, char z);

现在你可以传递它

void foo(FOOFUNC f) {
  f(...);
}
于 2010-04-04T03:20:29.203 回答
0

我完全理解 OP 想要做什么。事实上,我也想做同样的事情。按照 OP 所说的,我有以下内容(在 C 中,而不是 C++ 中):

/* File A.h */
typedef void (*f_t)(int x);

/* File B.h */
typedef void (*call_f_t)(f_t func2call,int y);

问题是,是否B.h必须包括A.hA.h定义了我不想包含在 Bh` 中的各种其他东西B.h', so I am hoping is a way to "forward reference" a function pointer, without redefining it in a typedef in(这可能甚至不起作用)?

或者编译器是否需要了解更多关于f_tin 的信息,B.h而不是关于前向引用的信息struct

我也可能需要重新考虑代码的布局,但我同意 OP,即在一个完美的世界中,函数指针和其他可以前向引用的对象之间应该存在某种对称性。

于 2017-05-19T18:01:04.060 回答
-1

完全有可能。你可以在任何你需要的地方复制你的函数原型,尽管当我看到这样做很多时,警钟开始响起。

于 2010-04-04T03:16:41.290 回答
-1

从您的问题中不清楚您要做什么。

首先,C++ 中没有“原型”之类的东西。“原型”(函数原型)的概念仅适用于 C 语言。

其次,您在消息正文中提到了一些“函数指针的原型”,而标题却谈到了“函数原型”。这使它更加混乱。“函数指针的原型”没有意义。即使在 C 中,也没有指针的“原型”之类的东西,更不用说 C++了。

那么,你想要做什么?如果您想前向声明一个函数 - 只需声明它。

如果您想前向声明一个指针 - 也只需声明它。为了获得对象的声明(非定义声明),只需用extern关键字声明即可。

于 2010-04-04T03:41:09.143 回答