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

Thiago Macieira thiago at kde.org
Tue Feb 8 12:00:30 CET 2011


Em terça-feira, 8 de fevereiro de 2011, às 11:33:38, Niels Dekker escreveu:
> However, this approach causes extra header file dependencies. So
> 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. Or even better: a const
> reference! 
> Protecting the Ui object against any accidental modifications!

Why a reference? What's the advantage here? In all platforms, references are 
just pre-dereferenced pointers. And how do you delete the reference 
afterwards?

You can also achieve the same with a const pointer to a const object:

    const Ui::CalculatorForm *const ui;

> Note that the ui reference does not need to be deleted. (It cannot even be
> deleted, of course, because it is not a pointer!) The argument of

It needs to be deleted. You can delete by prepending a &:

	delete &ui;

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

Uh... parent-child relationship only exists between QObject-derived classes. 
The Ui object isn't a QObject, so it doesn't participate in that. You have to 
delete on your own.

If you want to avoid the deletion code, use QScopedPointer:

	const QScopedPointer<const Ui::CalculatorForm> ui;

> 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?

> Is this idea of interest to anyone else here? I wouldn't mind sharing the
> implementation of CreateAndSetupUi. But I'm also interested to hear if such
> an approach is already presented elsewhere.

I don't think it works.

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;
}

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
  Senior Product Manager - Nokia, Qt Development Frameworks
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
Url : http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20110208/40579a5c/attachment.bin 


More information about the Qt-interest-old mailing list