# Smart pointers

All API classes provide smart pointers to simplify the object lifetime management. These pointer types automatically deallocate objects when they go out of scope or are reset unless the object is referenced by another smart pointer. These pointer types share the same name as the classes they reference, but have the prefix sp instead of I, such as spObject instead of IObject.

In Python and C#, only the sp objects are available.

# C++ API

void SmartPointerExample()
{ // Function scope..
    MyClass *myobject = NULL;
    // Create an object and assign its address to a smart pointer.
    spRidArray arr = sg->CreateRidArray();
    if( flag1 )
    { // 2nd scope...

        // Have another smart pointer point to the same object.
        // The object now has 2 references.
        spValueArray arr2( arr );

        // ... use arr2 ...
        if( flag2 )
        { // 3rd scope

            // A custom object is created that also keeps
            // a reference to the object. The reference
            // count is now 3.
            myobject = new MyClass( arr );
        }
        // arr2 goes out of scope. The
        // object now has 2 references.
    }
    // The custom object is deleted and reference count
    // decreases to 1.
    if( myobject )
        delete myobject;
    // Now arr goes out of scope, the object
    // has 0 references and is removed.
}

# Python API

In Python, scoping the code using a function is required for the deallocation to function. However - after having initialized Simplygon, it is only required to create one initial scope to which you pass the Simplygon interface object. In the example below the smart_pointer_example function is that required scope. The following example has additional (optional) scopes.

def third_scope(arr):
    # A custom object is created that also keeps a reference to the object.
    # The reference count is now 3.
    my_object = MyClass(arr)
    # my_object goes out of scope.

def second_scope(arr):
    # Second reference is created.
    arr_2 = Simplygon.spValueArray.SafeCast(arr)
    # Create a third scope.
    third_scope(arr)
    # The object count is now 2.
    # arr_2 goes out of scope.

def smart_pointer_example(sg):
    # Create an object
    arr = sg.CreateRidArray()
    # Have another smart pointer point to the same object in a new scope.
    second_scope(arr)
    # The object now has 1 reference.
    # Now arr goes out of scope, the object has 0 references and is removed.

# C# API

In C#, The using statement needs to be used whenever a method that returns a smart pointer (sp*) is called to avoid crashes and other unintended behavior caused by the garbage collector.

void SmartPointerExample()
{
    // Create an object.
    using (spRidArray arr = sg.CreateRidArray())
    {
        // 1st scope.
        // The object arr now has 1 reference.
        // Have another smart pointer point to the same object.
        using (spValueArray arr2 = Simplygon.spValueArray.SafeCast(arr))
        {
            // 2nd scope.
            // The object now has 2 references.
            // ... use arr2 ...
            // A custom object is created that also keeps a reference to the object.
            using (MyClass myObject = new MyClass(arr))
            {
                // 3rd scope.
                // The reference count is now 3.
                // ... use myObject ...
                // myObject goes out of scope.
            }
            // The object now has 2 references.
            // arr2 goes out of scope.
        }
        // The object now has 1 references.
        // Now arr goes out of scope.
    }
    // The object arr has 0 references and is removed.
}

# Checking for null

To check if a smart pointer is null in C++ and C#, call the dedicated IsNull() method on the sp object, or just compare it to 'None' in python.

    To check if a smart pointer is null in Python, compare the sp object directly with None:

    arr = sg.CreateBoolArray()
    if arr is None:
        # do something