[Qt-interest] A new (?) const-correct way to create a Ui objectand do setupUi

Niels Dekker (Qt-interest) mymailfromqt at xs4all.nl
Tue Feb 8 12:36:30 CET 2011


Thanks for your feedback.

>> doc.qt.nokia.com also presents an alternative, removing the #include
>> "ui_calculatorform.h" from the header file, and declaring the Ui
>> member variable as a pointer. I certainly find this an interesting
>> alternative. But instead of a pointer, I'd rather have a reference.

Thiago Macieira wrote:
> Why a reference? What's the advantage here?

During the lifetime of the form (e.g., CalculatorForm), its ui data member 
should never be NULL. So in my opinion, a reference to the Ui object is more 
appropriate than a pointer.

> And how do you delete the reference afterwards?

The Ui object is owned by the form. So it is deleted when the form is 
deleted.

> You can also achieve the same with a const pointer to a const object:
>    const Ui::CalculatorForm *const ui;

If you like pointers better than references, you can do so, of course.

>> CreateAndSetupUi(T&) is used as parent of the newly created Ui
>> object, so it will take care of deallocation.

> Uh... parent-child relationship only exists between QObject-derived
> classes. The Ui object isn't a QObject, so it doesn't participate in
> that.

Right. That's why I stored the Ui object inside a little helper class, 
derived from QObject. But that's an implementation detail of 
CreateAndSetupUi(T&). Are you interested to have a look at the entire code?

> If you want to avoid the deletion code, use QScopedPointer:
> const QScopedPointer<const Ui::CalculatorForm> ui;

That's also a possibility.

>> Actually the template function does not really return a reference to
>> the created Ui object. It returns a proxy object, which converts
>> implicitly to a (const) reference of the right Ui class type.
>
> Why the complexity?

Because it very much simplifies the Ui creation in the form class, IMO.

> I recommend using a pointer or a smart pointer:
>
> template <typename T, typename BaseWidget>
> const T *setupUi(BaseWidget *widget)
> {
>    T *ptr = new T;
>    ptr->setupUi(widget);
>    return ptr;
> }
>
> used in the constructor:
>  CalculatorForm::CalculatorForm(QWidget *parent)
>     : QWidget(parent),
>      ui(setupUi<Ui::CalculatorForm>(this))
>  {
>  }
>
> Where the member "ui" can be one of the ones I presented above. If
> it's a plain pointer, then you have to remember to delete in the
> destructor:
>
> CalculatorForm::~CalculatorForm()
> {
>    delete ui;
> }


I agree that a smart pointer is preferable to a raw pointer. But personally, 
I still prefer having ui as a reference. Is there anyone else here who 
prefers to have the Ui member variable as a reference?


Kind regards,

  Niels 




More information about the Qt-interest-old mailing list