[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