Before studying the video driver and scene graph of irrlicht, you must first understand the reference counting mechanism widely used in irrlicht. The ireferencecounted interface of irrlicht implements the reference counting mechanism. Classes that require reference count management inherit this interface. The two most important interfaces for IRR reference counting are grab () and drop ().
View plaincopy to clipboardprint?
Bool drop () const
{
// Someone is doing bad reference counting.
_ Irr_debug_break_if (referencecounter <= 0)
-- Referencecounter;
If (! Referencecounter)
{
Delete this;
Return true;
}
Return false;
}
Bool drop () const
{
// Someone is doing bad reference counting.
_ Irr_debug_break_if (referencecounter <= 0)
-- Referencecounter;
If (! Referencecounter)
{
Delete this;
Return true;
}
Return false;
}
Grab () simply adds one reference count, while drop () is the core of this mechanism. When drop () is followed by 0, the object instance deletes itself through Delete this, and finally releases the objects that are no longer used. Correct use of grab () and drop () is the core of the reference counting mechanism. When you want to hold an object for a long time, you need grab, then drop () him when he is no longer in use. After grab (), this object will not be released because of the drop in other places, because at least you still have references to it. If you only use an object in a function segment for a short time, you can skip grab or drop. Of course, you need to consider multithreading. In addition, if the object is created by you, but you cannot decide when to release it, you should add the object to an object and call drop (). This situation is also very common. For example, the following pseudo code:
Iimage * pimage = new cimage (...);
Pimagemanager-> Add (pimage); // In add, pimagemanager will call a grab ()
Pimage-> drop ();
In this way, it is easy to separate the creation and release of objects into different objects.
Of course, the reference of the counting mechanism also makes many people hate it, because it is a lot of trouble to use a mess. If it is a self-created object, you should be careful with the objects provided by the irrlicht engine. Generally, the object obtained using getxxx () does not need to be dropped (), unless you have grab. When using createxxx () or your new object, you need to ensure that it is dropped () somewhere, so you cannot go into the engine code to check it, we recommend that you use a visual memory leak monitoring tool such as VLD to help you find out where the memory is leaked.
There are also two notable issues.
1) The ireferencecounted interface is often virtualized, for example
Class iscenemanager: Public Virtual ireferencecounted
Because there are many reference counting interfaces and classes, it is possible that a class implements several interfaces, and these interfaces are inherited from ireferencecounted. The public virtual inheritance ensures that there is only one ireferencecounted base class object.
For example, class cscenemanager: Public iscenemanager and public iscenenode.
Because:
Class iscenenode: virtual public IO: iattributeexchangingobject
Class iattributeexchangingobject: virtual public ireferencecounted
And class iscenemanager: Public Virtual ireferencecounted
2) observe some interfaces in the irrlicht engine. Virtual destructor are not defined in the interfaces.
For example, class imesh: Public Virtual ireferencecounted, in include/imesh. h
This interface is connected ~ None of imesh (), nor virtual ~ Imesh.
According to C ++'s general thinking, if a class is clearly inherited, a virtual destructor needs to be defined. So why are many interfaces in irrlicht not defined? This is because it refers to the count. For example, there is an IBASE interface and its subclass cderived. If so
IBase * pbase = new cderived ();
When deleting pbase, if IBASE does not have a virtual destructor, The cderived destructor will not be correctly executed.
However, if IBASE inherits from ireferencecounted, we usually do not use Delete pbase to release this object. We will use pbase-> drop (). The problem is here. This drop () is the one defined by the ireferencecounted interface and will eventually execute Delete this, the type of this is the type of the object that calls drop (). This object is actually a subclass, so it will call the destructor of the subclass to further call the structure of the parent class, therefore, it doesn't matter if the parent class does not define virtual destructor. This is the trick to reference the count. Of course, some interfaces in the irrlicht engine also define virtual destructor, which has no impact, so it is safer, even if someone does not reference the counting method to manage the object's lifecycle. In my opinion, whether or not such a reference counting mechanism is used, it is better to add a virtual destructor to the parent class, which is more secure and clear.
This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/n5/archive/2009/07/12/4342758.aspx