Instantiation and Deallocation using Smart-Pointers

October 10

Raima logo on grey background

As outlined in previous post TBD:LINK we learned that the C++ interface for a particular database schema is generated by the schema compiler. These interfaces consist of a number of classes with public methods. Some methods common to more than one class (contained in a base class) while other methods are specific to a particular class (contained in a specialized class generated by the schema compiler).

Smart-pointers

The classes defining the interface (API classes) have one and only one member variable, a protected pointer, declared in the base classes. Thus, each of the two base classes have one pointer and there are no other member variables in any of these classes. The objects behind these pointers contain the main part of the implementation for the API. These objects will later be references to implementation class objects.

The pointers to the implementation class objects are implemented as smart-pointers (http://en.wikipedia.org/wiki/Smart_pointer) which implementation is hidden from the application developer. The reference counters are declared in the implementation classes and the API classes are using explicit public methods for the default constructor, copy constructor, assignment operator, and destructor to implement this.

The reference counter is initialized to one when the implementation object is instantiated. Instantiation is always a result of a method in any of the API classes being called. For the Db interface this is always any of the Open functions (declared as static methods in the Db interfaces) and for the Cursor interface it is a variety of methods both in the Db and the Cursor interfaces.

The reference counter is incremented whenever an additional object references it and decremented whenever one less object references it. We only account for pointers from an API object to an implementation object and any pointer from an implementation object for any of the Cursor interfaces to the implementation object for the Db interface. When the reference count is down to zero the implementation object is deallocated. This design ensures that whenever an implementation object can be referenced directly or indirectly from an API object the implementation objects will be kept but otherwise it will be deallocated.

The application developer then create static object instances of the API classes and passes them around by value as follows:

Cursor_sensor newRecord (Db_myDatabase dbPar) {
Cursor_myRecord cursor = dbPar.New_myRecord_record();
cursor.Set_name (“Tim”);

}

int main (intargc, char *argv[]) {

Db_myDatabase db= Db_myDatabase::Open ();
db.Initialize ();
Cursor_myRecord cursorNew= newRecord (db);

}

As shown in the above example the API class objects are instantiated each time they are passed around. In the above example. “Db_myDatabase::Open ()” instantiate a Db_myDatabase object with a reference count of one. This object is used with the copy constructor to initialize db in the main function incrementing the reference count to two. The first object that was instantiated is then destroyed which puts the reference count back to one.

The “newRecord (db)” instantiate yet another Db_myDatabase object for the formal parameter dbPar which increments the reference count to two. The function instantiates a Cursor_myRecord object with a reference count of one. This instantiation will also increment the reference count for the implementation object for the Db_myDatabase object to three.

The Cursor_myRecord object is used with the copy constructor to initialize cursor in the same way db was initialized in the main function. The first Cursor_myRecord object that was instantiated is then destroyed which decrements the reference count back to one. Yet another instantiation takes place for the object that is being returned from the function as cursor is being destroyed.

After the function have been returned and the Cursor_myRecord object have been assigned to cursorNew, the reference count for the Cursor_myRecord object is one while the reference count for the Db_myDatabase object is two.

When the main function returns db and cursorNew are destroyed which will decrement the reference counts down to zero and both the implementation objects will be destroyed.

Next TBD:LINK we give a short overview of the API.

Get notified about new RDM updates

Be the first to know about new Raima Database Manager updates when they go live, use cases, industry trends and more.