15 June 2013

Mastering Interfaces with QT

from high languages like java or c# interfaces are known since the very first time, unfortunately this feature is not available in c++. But c++ has a different feature that java for instance does not support: multi inheritance.

Now you may wonder how these obvious different things are connected? Quite simple: pure abstract classes can be used as interfaces; since c++ can inherit from multiple classes this is the solution for the missing interface feature.

Since all this is not very new and i guess you already know about this i promise now to speed up the out pointing.

meta object system and multiple inheritance

in general QT meta object system does not like multi inheritance whenever both classes inherit QObject, which is the recommended default scenario in each QT code tree.
It took me a while research how this problem can be solved in a QT compatible way. Looking backward is sounds totally easy, even if your interfaces inherit from each other: not let your interface inherit from QObject and use the macro Q_DECLARE_INTERFACE.

The following lines shows how this could look like:
// IContainer.h

class IContainer {

public:
    virtual bool isValid() = 0;
    virtual ~IContainer() {};
};
Q_DECLARE_INTERFACE(
    IContainer,
    "com.sample.Demo.IContainer/1.0"
)

Later when you want to implement a concrete class that support that interface you have to write one small macro to say the meta system that you implement a given interface Q_INTERFACES.
It could look like this:
// MessageContainerBase.h

#include "IContainer.h"

class MessageContainerBase : public QObject, 
                             public IContainer {
    Q_OBJECT
    Q_INTERFACES(IContainer)
public:
    MessageContainerBase();
    virtual             ~MessageContainerBase() { }

    virtual bool        isValid();
};

The Benefit

The main benefit is simple type safeness.
Type safeness in terms of down cast from a given pointer to that interface. With qobject_cast you can easily convert a QObject* into a IContainer* pointer with the safeness of typing. Means whenever you have QObject* or something else you can cast it into the Interface and can check if the resulting pointer is not null. If it is not null you can be sure that the instance supports your requested interface.
// Foo.cpp

#include "IContainer.h"

void Foo::bar(QObject* bak) {

    IContainer* container = NULL;
    bool valid = false;

    container = qobject_cast< IContainer* >(bak);
    if(container) {
        // inerface is supported, do some nice stuff
        valid = container->isValid();
    }
}

3 comments:

  1. Anal, but QT is quicktime, Qt is the toolkit ;p

    ReplyDelete
    Replies
    1. Next time i'll take care of it ;)

      Delete


  2. đất Yêu Linh này sẽ tìm Tham Lang hỏi cho rõ ràng.

    Ba người này lúc này không biết rằng, mọi chuyện khiến ba người tu sĩ có đại thần thông cao cao tại thượng khổ não toàn bộ đều do một người gây ra.
    dong tam
    game mu
    cho thuê phòng trọ
    cho thuê phòng trọ
    nhạc sàn cực mạnh
    tổng đài tư vấn pháp luật
    công ty luật
    số điện thoại tư vấn luật
    dịch vụ thành lập doanh nghiệp
    Lăng Thiên Hậu ấn một chưởng, mở cánh cửa Yêu Linh ra, tay áo vung lên, tiến vào ....

    Một chưởng đánh lên dòng xoáy Yêu Linh khiến cho chín quận trong vùng đất Yêu Linh trong một khắc ầm ầm chấn động.

    Trong vùng đất Yêu Linh phút chốc tràn ngập tiếng hô kinh ngạc. Bầu trời không còn xanh nữa mà âm u hẳn, tầng mây quay cuồng hình thành một cơn lốc khổng lồ.

    Cơn lốc này thực sự quá lớn, tràn ra mãi chân trời, không ngừng khuếch tán. Theo sự xoáy tròn của nó, từng đạo kiếm khí từ bên trong tỏa ra, dung nhập vào trong thiên địa.

    Một luồng khí tức cực kỳ bá đạo, dường như có thể so với trời từ nơi này truyền ra. Cùng lúc đó, bảy luồng sáng như cầu vồng từ trong cơn lốc phóng ra.

    ReplyDelete