Programming
Fundamentals
Setting Up Development Environment
Usage Examples
UnigineScript
High-Level Systems
C++
C#
UUSL (Unified UNIGINE Shader Language)
File Formats
Rebuilding the Engine and Tools
GUI
Double Precision Coordinates
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
Rendering-Related Classes

5. Working with Smart Pointers

<< RETURN TO THE PREVIOUS SECTION

In UNIGINE instances of C++ API classes (such as: node , mesh, body, image and so on...) only store pointers to instances of internal C++ classes, they cannot be created and deleted via the standard new / delete operators. So they should be declared as smart pointers (Unigine::Ptr) that allow you to automatically manage their lifetime. UNIGINE has its own optimized memory allocator for faster and more efficient memory management. Each smart pointer stores a reference counter, i.e. how many smart pointers are pointing to the managed object; when the last smart pointer is destroyed, the counter goes to 0, and the managed object is then automatically deleted.

To create an instance of a class we should declare a smart pointer for the class we are going to instantiate and call the create() method - class constructor - providing construction parameters if necessary.

Ownership of each instance matters on its deletion and can be managed using grab() and release() methods.

Source code (C++)
// instantiating an object of an internal class named object
<Class>Ptr instance = <Class>::create(<construction_parameters>);

// release ownership 
instance->release();

// grab ownership 
instance->grab();

// clears the smart pointer
instance.clear();

// destroys the smart pointer
instance.destroy();

The following example illustrates instancing for the NodeDummy class and difference between clearing and destroying smart pointers:

Source code (C++)
//--------------------------------------------------------------------
		// Case 1: clearing a smart pointer
//--------------------------------------------------------------------
// creating a NodeDummy (now reference counter = 1)
NodeDummyPtr ND1 = NodeDummy::create();

// setting the second pointer to point to the created NodeDummy (now reference counter = 2)
NodeDummyPtr ND2 = ND1;

// clearing ND1 pointer (now reference counter = 1)
ND1.clear();

// ND2 still has the object and we can manage it
ND2->setEnabled(1);

// clearing ND2 pointer (now reference counter = 0 and the object will be deleted automatically)
ND2.clear();

//--------------------------------------------------------------------
// Case 2: destroying a smart pointer
//--------------------------------------------------------------------
// creating a NodeDummy (now reference counter = 1)
NodeDummyPtr ND1 = NodeDummy::create();

// setting the second pointer to point to the created NodeDummy (now reference counter = 2)
NodeDummyPtr ND2 = ND1;

// destroying ND1 pointer (the object is deleted automatically)
ND1.destroy();

// ND2 is no longer accessible, so this line will lead to an error
ND2->setEnabled(1);

When creating a smart pointer you should remember about its scope, e.g. when you create a smart pointer inside a function, its scope is limited by this function.

Notice
You should avoid cyclic references!
If there is a ring, or cycle, of objects that have smart pointers to each other, they keep each other "alive" - they won't get deleted even if no other objects in the universe are pointing to them from "outside" of the ring. This cycle problem is illustrated in the diagram below that shows a container of smart pointers pointing to three objects each of which also point to another object with a smart pointer and form a ring. If we empty the container of smart pointers, the three objects won't get deleted, because each of them still has a smart pointer pointing to them.

Cyclic references

Additional information:

  • For more information on ownership management, see Memory Management page.
  • For more information on managing smart pointers, see Ptr class page.

PROCEED TO THE NEXT SECTION >>

Last update: 2017-07-03