c ++实例位置由fltk回调更改
c++ instance location changed by fltk callback
我正在尝试制作一个包含自己的回调函数的类似按钮的对象 (Smart_Button)。该对象是由 My_Window 构造函数创建的,但是当我按下 gui 按钮时它的内存地址与 My_Window 构造函数内部的地址不同。我想启用一些额外的功能,这些功能需要 Smart_Buttons 有指向彼此的指针,但我不能,因为地址改变了。
奇怪的是,如果我在 My_window 中定义回调函数(就像我在 site_parent_cb 中所做的那样),我会得到我期望的行为。当前程序的输出为:
site_parent_cb in constructor: 0xbfc20c6c
site_local_cb in constructor: 0xbfc20c48
(when I hit the "parent" button)
this: 0xbfc20c6c
(when I hit the "local" button)
this: 0xbfc20b90
我的代码如下。此外,我的 include 正在调用 Struustrups 的 Programming Principles and Practice Using C++ Book 中的文件。这些文件是一些 FLTK 功能的包装器,可在此处获得:http://www.stroustrup.com/Programming/PPP2code/
如果能帮助理解该行为,我们将不胜感激。我的主要问题是,这是否来自我自己不理解的代码,或者它是否是简化 FLTK 包装器的特性。
#include "GUI.h"
namespace Graph_lib {
struct Smart_Button : Button {
Smart_Button(Point tl, int w, int h, Callback cb);
Smart_Button(Point tl, int w, int h);
void print_address();
private:
static void cb_pressed(void*, void*);
};
Smart_Button::Smart_Button(Point tl, int w, int h, Callback cb)
:Button(tl, w, h, "parent", cb)
{
}
Smart_Button::Smart_Button(Point tl, int w, int h)
:Button(tl, w, h, "local", cb_pressed)
{
}
void Smart_Button::cb_pressed (void*, void* pw){static_cast<Smart_Button*>(pw)->print_address();}
void Smart_Button::print_address(){
cout << "this: " << this << endl;
}
struct My_Window : Window {
My_Window();
Smart_Button site_local_cb;
Smart_Button site_parent_cb;
private:
static void cb_pressed(void*, void*);
};
My_Window::My_Window()
:Window(Point(100,100),200,200,"Some App"),
site_parent_cb(Point( 50, 50), 40, 40, cb_pressed),
site_local_cb(Point(100, 50), 40, 40)
{
cout << "site_parent_cb in constructor: " << &site_parent_cb << endl;
cout << "site_local_cb in constructor: " << &site_local_cb << endl;
attach(site_parent_cb);
attach(site_local_cb);
}
void My_Window::cb_pressed (void*, void* pw){static_cast<My_Window>(pw)->site_parent_cb.print_address();}
};
int main(int argc, char **argv) {
using namespace Graph_lib;
My_Window game;
return gui_main();
}
问题出在回调
void My_Window::cb_pressed (void*, void* pw)
{
static_cast<My_Window>(pw)->site_parent_cb.print_address();
}
设置回调时,传入的参数是Smart_Button的地址。按下按钮时,回调将参数转换为 My_Window 并获取 site_parent_cb 的偏移量,它恰好与 My_Window 的地址有 4 个字节的偏移量。这就是地址存在差异的原因。回调应该是
void My_Window::cb_pressed(void*, void* pw)
{
static_cast<Smart_Button*>(pw)->print_address()
}
这是一个很好的收获。如果调换local和parent的位置,就永远不会发现差异了。
我正在尝试制作一个包含自己的回调函数的类似按钮的对象 (Smart_Button)。该对象是由 My_Window 构造函数创建的,但是当我按下 gui 按钮时它的内存地址与 My_Window 构造函数内部的地址不同。我想启用一些额外的功能,这些功能需要 Smart_Buttons 有指向彼此的指针,但我不能,因为地址改变了。
奇怪的是,如果我在 My_window 中定义回调函数(就像我在 site_parent_cb 中所做的那样),我会得到我期望的行为。当前程序的输出为:
site_parent_cb in constructor: 0xbfc20c6c
site_local_cb in constructor: 0xbfc20c48
(when I hit the "parent" button)
this: 0xbfc20c6c
(when I hit the "local" button)
this: 0xbfc20b90
我的代码如下。此外,我的 include 正在调用 Struustrups 的 Programming Principles and Practice Using C++ Book 中的文件。这些文件是一些 FLTK 功能的包装器,可在此处获得:http://www.stroustrup.com/Programming/PPP2code/
如果能帮助理解该行为,我们将不胜感激。我的主要问题是,这是否来自我自己不理解的代码,或者它是否是简化 FLTK 包装器的特性。
#include "GUI.h"
namespace Graph_lib {
struct Smart_Button : Button {
Smart_Button(Point tl, int w, int h, Callback cb);
Smart_Button(Point tl, int w, int h);
void print_address();
private:
static void cb_pressed(void*, void*);
};
Smart_Button::Smart_Button(Point tl, int w, int h, Callback cb)
:Button(tl, w, h, "parent", cb)
{
}
Smart_Button::Smart_Button(Point tl, int w, int h)
:Button(tl, w, h, "local", cb_pressed)
{
}
void Smart_Button::cb_pressed (void*, void* pw){static_cast<Smart_Button*>(pw)->print_address();}
void Smart_Button::print_address(){
cout << "this: " << this << endl;
}
struct My_Window : Window {
My_Window();
Smart_Button site_local_cb;
Smart_Button site_parent_cb;
private:
static void cb_pressed(void*, void*);
};
My_Window::My_Window()
:Window(Point(100,100),200,200,"Some App"),
site_parent_cb(Point( 50, 50), 40, 40, cb_pressed),
site_local_cb(Point(100, 50), 40, 40)
{
cout << "site_parent_cb in constructor: " << &site_parent_cb << endl;
cout << "site_local_cb in constructor: " << &site_local_cb << endl;
attach(site_parent_cb);
attach(site_local_cb);
}
void My_Window::cb_pressed (void*, void* pw){static_cast<My_Window>(pw)->site_parent_cb.print_address();}
};
int main(int argc, char **argv) {
using namespace Graph_lib;
My_Window game;
return gui_main();
}
问题出在回调
void My_Window::cb_pressed (void*, void* pw)
{
static_cast<My_Window>(pw)->site_parent_cb.print_address();
}
设置回调时,传入的参数是Smart_Button的地址。按下按钮时,回调将参数转换为 My_Window 并获取 site_parent_cb 的偏移量,它恰好与 My_Window 的地址有 4 个字节的偏移量。这就是地址存在差异的原因。回调应该是
void My_Window::cb_pressed(void*, void* pw)
{
static_cast<Smart_Button*>(pw)->print_address()
}
这是一个很好的收获。如果调换local和parent的位置,就永远不会发现差异了。