你为何不应在意它
许多由wxPython包装的C++对象使用了一种被称为引用计数的技术,也叫做写时复制(COW)。这意味着当一个对象被赋值给另一个对象时,实际上并没有发生复制操作。只是共享对象数据的引用计数会增加,并且两个对象会共享相同的数据(这是一个非常快速的操作)。
但是,一旦两个(或更多)对象中的一个被修改,就必须复制数据,因为对其中一个对象的修改不应在其他对象中体现出来。由于数据复制仅在对象被写入时才会发生,所以这被称为写时复制。
重要的是要明白,所有这些对于类的使用者来说都是完全透明的,而且一个对象是否被共享从类的外部是看不出来的——无论如何,对它进行任何操作的结果都是一样的。
对象比较
引用计数类的“==”和“!=”运算符总是执行深度比较。这意味着,当两个对象完全相同,而不仅仅是它们共享相同数据时,相等运算符才会返回true。
请注意,wxPython遵循标准模板库(STL)的理念:当一个比较运算符无法高效实现时(例如,wx.Image的“==”运算符需要逐像素地比较整个图像的数据,这种情况就无法高效实现),它就根本不会被实现。
这就是为什么并非所有引用计数类都提供比较运算符。 另外还要注意,如果你只需要对两个派生自wx.Object的类进行浅度比较,你不应该使用“==”和“!=”运算符,而应该使用wx.Object.IsSameAs()函数。
对象销毁
当调用一个写时复制(COW)对象的析构函数时,它可能不会删除数据:如果该数据是共享的,析构函数只会减少共享数据的引用计数,而不会销毁数据。只有当最后一个拥有该数据的对象的析构函数被调用时,数据才会真正被销毁。就像所有其他与写时复制相关的操作一样,这对于类的使用者来说是完全透明的,所以你无需在意这一点。
引用计数类列表
以下wxPython中的类具有高效(即快速)的赋值运算符和复制构造函数,因为它们是基于引用计数的:
- wx.AcceleratorTable
- wx.adv.Animation
- wx.Bitmap
- wx.Brush
- wx.Cursor
- wx.Font
- wx.GraphicsBrush
- wx.GraphicsContext
- wx.GraphicsFont
- wx.GraphicsMatrix
- wx.GraphicsPath
- wx.GraphicsPen
- wx.Icon
- wx.Image
wx.msw.Metafile- wx.Palette
请注意,上面的列表列出了在wxPython的所有端口中都采用引用计数的对象;某些端口可能也会对其他类使用这种技术。