为什么 Widget class 使用指针作为数据成员?
Why a Widget class uses pointers as data members?
我正在研究“编程原理与实践”,我不明白为什么这个Widget
class使用指针作为数据成员。
书中的解释是这样的:
Note that our Widget keeps track of its FLTK widget and the Window with which it is associated. Note that we need pointers for that because a Widget can be associated with different Windows during its life. A reference or a named object wouldn’t suffice. (Why not?)
所以,我仍然不明白为什么 Widget
不能将命名对象 Window win
作为数据成员,当它与不同的 Window
。有人可以解释一下吗?
class Widget {
// Widget is a handle to a Fl_widget — it is *not* a Fl_widget
// we try to keep our interface classes at arm’s length from FLTK
public:
Widget(Point xy, int w, int h, const string& s, Callback cb)
:loc(xy), width(w), height(h), label(s), do_it(cb) { }
virtual ~Widget() { } // destructor
virtual void move(int dx,int dy)
{ hide(); pw–>position(loc.x+=dx, loc.y+=dy); show(); }
virtual void hide() { pw–>hide(); }
virtual void show() { pw–>show(); }
virtual void attach(Window&) = 0; // each Widget defines at least one action for a window
Point loc;
int width;
int height;
string label;
Callback do_it;
protected:
Window* own; // every Widget belongs to a Window
Fl_Widget* pw; // a Widget “knows” its Fl_Widget
};
Window own;
这将复制整个 Window 对象。如果真正的 window 发生变化,这个小部件将有一个旧的无用的副本。
Window & own;
一个参考。我们遇到两个问题:
- A) 我们无法知道window 是否在widget 代码外被删除
- B) window 必须在此小部件
之前存在
Window * own;
与引用相反,指针可以为 NULL。这避免了引用问题。
这本书看起来有点旧,只是因为它使用了原始指针。
编辑 由于评论
问题“A)”对于引用和指针来说是相同的,这是绝对正确的。但是用指针可以更容易地处理它。
我想指出的是,当一个window被删除时,widget必须被告知它,以免使用“自己的”对象。
使用指针,可以将其重置为 NULL,因此可以轻松捕获任何进一步使用“own”的尝试。但是对于引用,您至少需要在代码中添加一个额外的 bool
来存储“own”是否有效。
首先,我们需要制定逻辑和实施细节。在逻辑方面,window 包含小部件:就像母亲有 children 一样。这是一对多的关系。每个小部件都有一个实现实体,在本例中为 Fl_widget。它同样可以是 MS windows Window、QtWidget 或 X-Windows Widget。它是那些依赖于实现的东西之一
___________
|window |
| _______ | _________
| |widget-|-|--->|Fl_widget|
| _______ | _________
| |widget-|-|--->|Fl_widget|
|___________|
在 window 本身中,也会有一个类似于另一个 Fl_Widget 或 Fl_window 的实现细节。
为什么我们不能Window赢而不是Window赢* 是因为 window 拥有小部件,而不是相反。如果我们有 Window win 那么每当任何 window 属性 发生变化时,您都必须修改所有包含相同 [=39= 的小部件].以母child关系为例,如果母亲剪了头发,同一个母亲的所有child人的母亲成员都要剪头发。您必须有一种方法来跟踪和更新所有 children 的所有母亲。这将只是一场维护噩梦。
如果我们只持有指向 window 的指针,那么我们知道如果 window 被修改,所有同级小部件将能够查询 parent window 并且不费吹灰之力就得到了相同的答案。
关于在 windows 之间移动小部件的问题的第二部分 - 我从未见过有人这样做。在我曾经使用过的所有实现中,这是不可能的。 parent window 终生拥有该小部件。要“移动它”,您通常必须重新生成它,即从当前的 window 和 re-create 中销毁它到新的 window.
我正在研究“编程原理与实践”,我不明白为什么这个Widget
class使用指针作为数据成员。
书中的解释是这样的:
Note that our Widget keeps track of its FLTK widget and the Window with which it is associated. Note that we need pointers for that because a Widget can be associated with different Windows during its life. A reference or a named object wouldn’t suffice. (Why not?)
所以,我仍然不明白为什么 Widget
不能将命名对象 Window win
作为数据成员,当它与不同的 Window
。有人可以解释一下吗?
class Widget {
// Widget is a handle to a Fl_widget — it is *not* a Fl_widget
// we try to keep our interface classes at arm’s length from FLTK
public:
Widget(Point xy, int w, int h, const string& s, Callback cb)
:loc(xy), width(w), height(h), label(s), do_it(cb) { }
virtual ~Widget() { } // destructor
virtual void move(int dx,int dy)
{ hide(); pw–>position(loc.x+=dx, loc.y+=dy); show(); }
virtual void hide() { pw–>hide(); }
virtual void show() { pw–>show(); }
virtual void attach(Window&) = 0; // each Widget defines at least one action for a window
Point loc;
int width;
int height;
string label;
Callback do_it;
protected:
Window* own; // every Widget belongs to a Window
Fl_Widget* pw; // a Widget “knows” its Fl_Widget
};
Window own;
这将复制整个 Window 对象。如果真正的 window 发生变化,这个小部件将有一个旧的无用的副本。
Window & own;
一个参考。我们遇到两个问题:
- A) 我们无法知道window 是否在widget 代码外被删除
- B) window 必须在此小部件 之前存在
Window * own;
与引用相反,指针可以为 NULL。这避免了引用问题。
这本书看起来有点旧,只是因为它使用了原始指针。
编辑 由于评论
问题“A)”对于引用和指针来说是相同的,这是绝对正确的。但是用指针可以更容易地处理它。
我想指出的是,当一个window被删除时,widget必须被告知它,以免使用“自己的”对象。
使用指针,可以将其重置为 NULL,因此可以轻松捕获任何进一步使用“own”的尝试。但是对于引用,您至少需要在代码中添加一个额外的 bool
来存储“own”是否有效。
首先,我们需要制定逻辑和实施细节。在逻辑方面,window 包含小部件:就像母亲有 children 一样。这是一对多的关系。每个小部件都有一个实现实体,在本例中为 Fl_widget。它同样可以是 MS windows Window、QtWidget 或 X-Windows Widget。它是那些依赖于实现的东西之一
___________
|window |
| _______ | _________
| |widget-|-|--->|Fl_widget|
| _______ | _________
| |widget-|-|--->|Fl_widget|
|___________|
在 window 本身中,也会有一个类似于另一个 Fl_Widget 或 Fl_window 的实现细节。
为什么我们不能Window赢而不是Window赢* 是因为 window 拥有小部件,而不是相反。如果我们有 Window win 那么每当任何 window 属性 发生变化时,您都必须修改所有包含相同 [=39= 的小部件].以母child关系为例,如果母亲剪了头发,同一个母亲的所有child人的母亲成员都要剪头发。您必须有一种方法来跟踪和更新所有 children 的所有母亲。这将只是一场维护噩梦。
如果我们只持有指向 window 的指针,那么我们知道如果 window 被修改,所有同级小部件将能够查询 parent window 并且不费吹灰之力就得到了相同的答案。
关于在 windows 之间移动小部件的问题的第二部分 - 我从未见过有人这样做。在我曾经使用过的所有实现中,这是不可能的。 parent window 终生拥有该小部件。要“移动它”,您通常必须重新生成它,即从当前的 window 和 re-create 中销毁它到新的 window.