On Mon, May 06, 2019 at 07:41:05AM +0000, Lars Knoll wrote:
> > On 6 May 2019, at 09:30, Christian Kandeler
> > <christian.kande...@qt.io> wrote:
> > 
> > On Sat, 04 May 2019 09:06:39 +0200 Allan Sandfeld Jensen
> > <k...@carewolf.com> wrote:
> > 
> >> On Samstag, 4. Mai 2019 00:43:10 CEST Thiago Macieira wrote:
> >>> On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
> >>>> Which should be considered bad practice and banned on an API
> >>>> level
> >>> 
> >>> No way.
> >>> 
> >>> Are you going to forbid creation of QFile on the stack?
> >> 
> >> Perhaps QFile shouldn't be the same kind of base object type as
> >> QWidgets? Or not use the same smart pointer.
> >> 
> >> Though even making QWidgets not allowed on the stack, while
> >> sensible, would break a many of our tests, where we "abuse" that it
> >> is technically possible in simple cases.
> > 
> > Doesn't almost every project create its main widget on the stack? 
> 
> Not sure whether it’s most projects, but there certainly are users
> doing it. And we’ve been using the pattern in our examples in some
> cases as well. But I can relate to Allan that creating widgets on the
> stack is bad style (as it conflicts with the way we memory manage
> them), and if I’d have a choice today, I would probably prefer to
> enforce them to be created on the heap by some means.

I wonder whether there's a solution in the following direction:

Have something like the following for each QObject derived class Foo
(for which it makes sense. E.g. perhaps all widgets, but not QFile):

namespace Qt {

class Foo 
{
public:
   Foo() : p(new QFoo), owning(true) {} 
    // more ctors forwarding to QFoo ctor

   ~Foo() { if (owning) delete p; }

    // make  movable but not copiable...

   // forward QFoo interface to p->

private:
   QPointer<QFoo> p;  // Maybe QFoo *p.
   bool owning;  // Perhaps somehow mangled into p
   ...
   // whatever else is needed. Shouldn't be much.
};

} // namespace Qt

Those things could be 'stack only', and be reasonably explicit
about ownership without being too much of a pain to use.

Example code could be sth like:

int main(...)
{
   // a will own its a.p, and will destroy it when w itself dies.
   Application a(...);

   // w will own its w.p, and will destroy it when w itself dies.
   MainWindow w;

   // addChild<Foo> would forward to QFoo's constructor and set 'owning'
   // to false on the resulting Foo, i.e. l is now known to be owned
   //  by something else, and will not destroy l.p in its dtor
   // w takes ownership of l, e.g. using the classic QObject
   // parent/child mechanisme on w.p and l.p. Or something else.
   Label l = w.addChild<Label>("Something"); 

   l.setSomething(..,); // call l.p->setSomething(...)

   w.show();  // call w.p->show()

   return a.exec(); // call a.p->show()

   // l will be destroyed, but not l.p as l.owning == false
   // w will be destroyed including w.p, and trigger the
   //   destruction of QItems created/owned by it, e.g. l.p 
   // a will be destroyed including a.p
}

The main benefits I see here that this scheme can co-exist with current
code, i.e. code bases could slowly opt-in and migrate step by step, and
it does not add the need to sprinkle user side code with the typical
smart pointer line noise.

Andre'
_______________________________________________
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to