我正在为我的 OpenGL 游戏创建小 GUI。我有两个基类Widget
和Container
. Widget
类有类似setPosition(x,y)
, setSize(w,h)
,... 的方法 这些方法应该只对从 . 派生的类可见Container
。
编辑:我可以用朋友和包装器方法来做,但我想不用包装器来做。
我正在为我的 OpenGL 游戏创建小 GUI。我有两个基类Widget
和Container
. Widget
类有类似setPosition(x,y)
, setSize(w,h)
,... 的方法 这些方法应该只对从 . 派生的类可见Container
。
编辑:我可以用朋友和包装器方法来做,但我想不用包装器来做。
如果评论中的建议不清楚,您可以考虑使用该方法的子集创建一个接口,并在Widget
. 然后使用一个受保护的(单个操作)Container
来获取从它派生的类的私有接口:
struct Drawable { // choose a better name
virtual void setPosition( int x, int y );
virtual void setSize( int w, int h );
virtual ~Drawable() {}
};
class Widget : private Drawable {
friend class Container;
};
class Container {
protected:
Drawable& getDrawable( Widget& w ) { return w; };
};
class MyContainer : public Container {
void changeSize( Widget & w ) {
getDrawable(w).setSize(10,20);
}
};
转发选项的主要区别在于,它可以更好地扩展功能数量并且更易于维护(无需更新 N 转发器,只需访问正确接口的访问器)。
从高级设计的角度来看, aWidget
不是Drawable
一般的,它只是Drawable
来自Widget
or的上下文Container
。
我害怕写这个答案,因为它看起来太明显了,但你不能让setPosition(x,y)
和setSize(w,h)
成员Container
吗?
或者,如果存在某种未知的复杂性,您可以将 aWidgetContainer
作为基类并将这些方法放入该类中吗?
在我看来,这是“我能做些什么让另一个程序员在做错事时感到肮脏”的情况之一:语言没有很好地处理它,所以你不想过分限制您的代码,因为这往往会使事情变得混乱。在我看来,Friend-container-delegate 设置只会让那些试图在日常“这是如何工作”的情况下弄清楚你的代码的人感到困惑。你想让在“我需要破解这个”的情况下更难滥用你的代码。
我要做的可能是简单的文档以及调用(公共)函数_setPosition
和_setSize
. 下划线将(希望)让其他程序员去,“wha???” 并阅读您的文档 - 这将准确解释为什么非Container
s 调用这些函数是一个非常糟糕的主意。
这有点难看,但这就是重点。rect._setPosition
如果不了解发生了什么,我肯定会感到肮脏。这是一种心理解决方案,但在缺乏访问保护设施的其他语言(如 Javascript)中大量使用,因此并没有那么不寻常,以至于丑得可怕。或者至少,不会比试图在语言特性中指定您的要求更丑陋:)