我有一个函数指针定义:
typedef void (*EventFunction)(int nEvent);
Run Code Online (Sandbox Code Playgroud)
有没有办法用特定的C++对象实例处理该函数?
class A
{
private:
EventFunction handler;
public:
void SetEvent(EventFunction func) { handler = func; }
void EventOne() { handler(1); }
};
class B
{
private:
A a;
public:
B() { a.SetEvent(EventFromA); } // What do I do here?
void EventFromA(int nEvent) { // do stuff }
};
Run Code Online (Sandbox Code Playgroud)
编辑: Orion指出了Boost提供的选项,例如:
boost::function<int (int)> f;
X x;
f = std::bind1st(
std::mem_fun(&X::foo), &x);
f(5); // Call x.foo(5)
Run Code Online (Sandbox Code Playgroud)
不幸的是Boost对我来说不是一个选择.是否有某种"currying"函数可以用C++编写,它会将指向成员函数的指针包装到普通函数指针中?
这听起来像是一个愚蠢的问题,但我还在学习C,所以请耐心等待.:)
我正在研究K&R(结构)的第6章,到目前为止,这本书已经取得了巨大的成功.我决定使用相当多的结构,因此在本章的早期就使用了point和rect示例做了很多工作.我想尝试的其中一件事是canonrect通过指针改变功能(第2版,第131页),然后返回void.
我有这个工作,但遇到一个打嗝,我希望你们可以帮助我.我想canonRect创建一个临时矩形对象,执行其更改,然后重新分配它传递给临时矩形的指针,从而简化代码.
但是,如果我这样做,矩形不会改变.相反,我发现自己手动重新填充我传入的矩形字段,这确实有效.
代码如下:
#include <stdio.h>
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
struct point {
int x;
int y;
};
struct rect {
struct point lowerLeft;
struct point upperRight;
};
// canonicalize coordinates of rectangle
void canonRect(struct rect *r);
int main(void) {
struct point p1, p2;
struct rect r;
p1.x = 10;
p1.y = 10;
p2.x = 20;
p2.y …Run Code Online (Sandbox Code Playgroud) 鉴于所有原始数据类型和对象都分配了内存,因此直观地容易想象指向这些类型的指针.
但是函数指针究竟指向哪里?鉴于指令被转换为机器代码并驻留在内存中,我们是否应该考虑它们指向与函数指令开头相对应的内存位置?
由于非法内存访问,我们在指针中面临许多错误.当函数指针指向数据存储器而不是指令存储器时,是否会发生错误?
我已经开始回顾回调了.我在SO上找到了这个链接: C中的"回调"是什么?它们是如何实现的? 它有一个很好的回调示例,它与我们在工作中使用的非常类似.但是,我试图让它工作,但我有很多错误.
#include <stdio.h>
/* Is the actual function pointer? */
typedef void (*event_cb_t)(const struct event *evt, void *user_data);
struct event_cb
{
event_cb_t cb;
void *data;
};
int event_cb_register(event_ct_t cb, void *user_data);
static void my_event_cb(const struct event *evt, void *data)
{
/* do some stuff */
}
int main(void)
{
event_cb_register(my_event_cb, &my_custom_data);
struct event_cb *callback;
callback->cb(event, callback->data);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道回调使用函数指针来存储函数的地址.但是我发现有些事情我不明白:
什么是Windows任务管理器"处理"列的度量?文件句柄?或页面文件指针?一个程序有8000个句柄也不好吗?
我有以下代码:
$data['x'] = $this->x->getResults();
$data['y'] = $data['x'];
//some code here to modify $data['y']
//this causes (undesirably) $data['x] to be modified as well
Run Code Online (Sandbox Code Playgroud)
我猜因为$ data的所有元素都是引用,修改$ data ['y']也会修改$ data ['x'] ..这不是我想要的.我希望$ data ['x']保持不变.有没有办法取消引用这里的元素,以便我可以按值复制元素?
谢谢.
更新:$ this-> x-> getResults(); 返回一个对象数组.所以我可以做类似的事情:$ data ['x'] [0] - > date_create ...
更新:我最近克隆数组的尝试看起来像这样:
$data['x'] = $this->x->getResults();
$data['y'] = $data['y'];
foreach($data['x'] as $key=>$row) {
$data['y'][$key]->some_attr = clone $row->some_attr;
}
Run Code Online (Sandbox Code Playgroud)
我离开这里了吗?我一直得到一个"非对象调用的__clone方法"错误.从阅读响应看来,我最好的选择是迭代每个元素并克隆它(这是我试图用该代码做的事情......).
更新:刚刚解决了!:在foreach循环中我只需要将行更改为:
$data['y'][$key] = clone $row;
Run Code Online (Sandbox Code Playgroud)
它的工作原理!感谢大家的帮助.
我想我已经在某处读过,在C中取一个枚举值的地址是非法的(枚举值不是左值;但是,我现在找不到任何关于此的信息).这是正确的,如果是的话,为什么?
编辑:
这是一个例子,用上面的"枚举值"来澄清我的意思.我的意思是取first_value下面的地址,而不是获取枚举的实际实例的地址:
enum myenum
{
first_value,
second_value
};
Run Code Online (Sandbox Code Playgroud) 我目前正在使用GCC 4.4,而且我之间void*有一个令人头痛的问题,并且指向成员函数.我正在尝试编写一个易于使用的库,用于将C++对象绑定到Lua解释器,如下所示:
LuaObject<Foo> lobj = registerObject(L, "foo", fooObject);
lobj.addField(L, "bar", &Foo::bar);
Run Code Online (Sandbox Code Playgroud)
我已经完成了大部分工作,除了以下函数(特定于某个函数签名,直到我有机会对其进行概括):
template <class T>
int call_int_function(lua_State *L)
{
// this next line is problematic
void (T::*method)(int, int) = reinterpret_cast<void (T::*)(int, int)>(lua_touserdata(L, lua_upvalueindex(1)));
T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1));
(obj->*method)(lua_tointeger(L, 2), lua_tointeger(L, 3));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
对于那些不熟悉Lua的人,lua_touserdata(L, lua_upvalueindex(1))获取与闭包相关的第一个值(在这种情况下,它是指向成员函数的指针)并将其作为a返回void*.海湾合作委员会抱怨说void*- > void (T::*)(int, int)是无效的演员.关于如何解决这个问题的任何想法?