Smart Pointers (C++)

Smart pointers are very useful feature of modern C++ programming model.

They are defined in the std namespace in the <memory> header file.

Let’s see the raw and smart pointer in action:

void rawPointer() {
    sql::Driver * driver = sql::mysql::get_driver_instance();
    sql::Connection* connection = driver->connect(host, user, pass);
//use connection

//remember
    delete driver;
    delete connection;
}
void smartPointer() {
    std::shared_ptr<sql::Driver> driver(sql::mysql::get_driver_instance());
    std::shared_ptr< sql::Connection > con(driver->connect(host, user, pass));
//use connection
}
//shared pointers are deleted when all pointer owners have gone out of their scope or given up ownership

As we can see there is a clear advantage of using smart pointers instead of the raw ones.

The standard library provide three smart pointer types which should be replacement for raw pointers as long as new code is developed:

  • unique_ptr
    • allows one and only one owner of the underlying pointer
    • deleted when the owner goes out of scope it is defined in
    • cannot be shared
    • cannot be copied
    • small and efficient
  • shared_ptr
    • underlying pointer can be shared between multiple owners
    • not deleted till all owners have gone out of scope or given up ownership
    • can be shared
    • the size is equal to two pointers: one for the raw pointer, one for the block containing the reference count
  • weak_ptr
    • use in conjunction with shared_ptr
    • provides access to a raw pointer which is owned by one or more shared pointer instances but does not take part in reference counting
    • deleted when the only reference to the object is weak_ptr reference

I firstly realized the difference between unique_ptr and shared_ptr when tried to create a unique_ptr and share it among two different objects:

std::shared_ptr<sql::Driver> driver(sql::mysql::get_driver_instance()); 
std::unique_ptr< sql::Connection > con(driver->connect(host, user, pass)); 
std::unique_ptr< sql::Statement > stmt(con->createStatement()); 
stmt->execute("USE " + db); 
studentsDAO.setConnection(con); 
groupsDAO.setConnection(con);

Obviously, it cannot be done and the error is raised.

When unique_ptr is replaced by shared_ptr everything works all right. Connection object can  be shared between two DAO objects and we are assured that the pointer is deleted when it is not needed by any of the owners:

std::shared_ptr<sql::Driver> driver(sql::mysql::get_driver_instance()); 
std::shared_ptr< sql::Connection > con(driver->connect(host, user, pass)); 
std::shared_ptr< sql::Statement > stmt(con->createStatement()); 
stmt->execute("USE " + db); 
studentsDAO.setConnection(con); 
groupsDAO.setConnection(con);

Visual C++ DataGridView – data binding

DataGridView is a control introduced in .NET Framework version 2.0. displaying data in customizable grid.  The control can be used in any application developed on .NET Framework using any language (C++, C#, VB) based on CLR (Common Language Runtime).
The control can be customized through manipulating of DataGridView class properties. Some of them are: DefaultCellStyle, CellBorderStyle, GridColor, just to name a few.
That is the short introduction do DataGridView Control. However, what I would like to concentrate in this post is specifying a data source for the control. There are several ways introduced in MSDN documentation:

DataGridView::DataSource Property

What was needed to implement in an application was using as a datasource some collection of simple POCO’s (Plain Old C/C++ Object).

So going this way, a POCO is needed:

ref class StudentDataGridItem
{
    Int32^ _id;
    String^ _name1;
    String^ _name2;
    String^ _surname;  //leave more properties in sake of readibility
public:
    StudentDataGridItem(void);
    property int^ id     {       Int32 ^ get() {
        return _id;
    }       void set ( Int32^ value) {
        _id = value;
    }     }      property String^ name1     {       String^ get() {
        return _name1;
    }       void set ( String^ value) {
        _name1 = value;
    }     }      property String^ name2     {       String^ get() {
        return _name2;
    }       void set ( String^ value) {
        _name2 = value;
    }     }      property String^ surname     {       String^ get() {
        return _surname;
    }       void set ( String^ value) {
        _surname = value;
    }     }
};

The collection of objects of the above class is returned from a simple DAO:

ArrayList^ StudentsDAO::getStudents()
{
 Statement* stmt = conn->createStatement();
 ResultSet *res;
 ArrayList^ students = gcnew ArrayList();
 try{ 
  res = stmt -> executeQuery ("SELECT u.user_id as id, surname, name_1 as name1, name_2 as name2 FROM user u, student_extra s where u.user_id = s.user_id AND deleted = 0"); 
  
  while (res -> next()) {
   StudentDataGridItem^ student = gcnew StudentDataGridItem();
   student->id = res->getInt("id");
   student->surname= StringUtils::stdStringToSystemString(res->getString("surname"));
   student->name1 = StringUtils::stdStringToSystemString(res->getString("name1"));
   student->name2 = StringUtils::stdStringToSystemString(res->getString("name2"));

   students->Add(student);
  }
 }catch (SQLException &e) {
  //exception dealing logic
 }
 return students; 
}

and bound to DataGridViewControl:

this->studentsDataGridView->DataSource = (System::Object ^) studentsDAO.getStudents();

What is assumpted is that control has columns specified with DataPropertyName equal to the property from POCO from which value goes to the particular column.

As a result data grid with proper columns is displayed, hovewer it contains no data. DAO returns data, it is bound to grid’s data source but nothing is displayed. What is more, it works perfectly in C# and probably in VB (not tested by myself) but not in C++.

To make it work, Bindable (documentation: MSDN BindableAttribute Class) attribute is needed to be specified on each and every property which is bound to the data grid column. The proper POCO should look like this:

 ref class StudentDataGridItem
{ 
 Int32^ _id;
 String^ _name1;
 String^ _name2;
 String^ _surname;
 //leave more properties in sake of readibility
public:
 StudentDataGridItem(void);

    [System::ComponentModel::Bindable(true)]
    property int^ id
    {
      Int32 ^   get() { return _id; }
      void set ( Int32^ value) { _id = value; }
    }
    
    [System::ComponentModel::Bindable(true)]
    property String^ name1
    {
      String^   get() { return _name1; }
      void set ( String^ value) { _name = value; }
    }

    [System::ComponentModel::Bindable(true)]
    property String^ namee2
    {
      String^   get() { return _name2; }
      void set ( String^ value) { _name2 = value; }
    }

    [System::ComponentModel::Bindable(true)]
    property String^ surname
    {
      String^   get() { return _surname; }
      void set ( String^ value) { _surname = value; }
    }
};

Now, everything works properly and data grid displays data from the bound collection.

ActiveMQ-CPP bug

I was faced with strange bug in ActiveMQ-CPP library recently.
I just wanted to make sure that message broker (ActiveMQ) redelivers not acknowledged messages to the consumer applying some delay. For example 10 seconds.
Let’s say that consumer processes message and some error occurs like there is no connectivity to the external system where processed message is stored. I do not want the message to be lost but rather returned to the broker and redelivered after some time.
Quick look at the API and documentation and it is clear that such behavior can be implemented using RedeliveryPolicy.
There are some properties which can be used to adjust the policy:

Option Name Default Description
cms.RedeliveryPolicy.backOffMultiplier 5.0 Used to extend the redelivery window when the _useExponentialBackOff option is enabled.
cms.RedeliveryPolicy.collisionAvoidancePercent 15 Percentage of randomness to add to redelivery backoff to keep multiple consumers in a rollback from redelivering at the same time.
cms.RedeliveryPolicy.initialRedeliveryDelay 1000 Amount of time to wait before starting redeliveries, in milliseconds.
cms.RedeliveryPolicy.maximumRedeliveries 6 Maximum number of time to attempt a redelivery before giving up and NAck’ing the message.
cms.RedeliveryPolicy.useCollisionAvoidance false Should the Random avoidance percentage be added into the redelivery delay.
cms.RedeliveryPolicy.useExponentialBackOff false Should redeliveries be slowed on each cycle.

Unfortunately, even if I tried almost all possible combination I could not forced the broker to redeliver messages after specified redelivery delay. Messages came back to the consumer immediately. It caused really high processor utilization and, what is more, log files were growing very quickly.

As last resort I dived into library source code and that is what I found there:

if( internal->redeliveryDelay > 0 && !this->internal->unconsumedMessages->isClosed() ) {
    // TODO - Can't do this until we can control object lifetime.
    // Start up the delivery again a little later.
    // this->internal->scheduler->executeAfterDelay(
    // new StartConsumerTask(this), internal->redeliveryDelay);
    start();
} else {
    start();
}

That must be a joke… API gives you a way to set redelivery delay, documentation says it can be done… But that is what you find in the source code.
Just to be proper I use 3.4.5 version of the library and the bug is fixed in 3.5.0 version.