diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2015-03-30 17:49:20 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-04-10 13:13:53 +0100 |
commit | 582e89610b366c0d887baa6b8de7fa5f065900fa (patch) | |
tree | 91f3b723d1485b5616d457e30011fa55914785a4 /vcl/README.lifecycle | |
parent | 49dadad0b55f879ebe5daf539a97043d283ad0a8 (diff) |
vclptr: create Instance helpers, and set initial ref-count to 1.
Document that in README.lifecycle; the problem is that our constructors
currently take and release references left/right on the object being
created, which ... means we need an initial reference.
Change-Id: I5de952b73ac67888c3fbb150d4a7cde2a7bc9abf
Diffstat (limited to 'vcl/README.lifecycle')
-rw-r--r-- | vcl/README.lifecycle | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/vcl/README.lifecycle b/vcl/README.lifecycle index 26e7a348cc39..6a9e080c176a 100644 --- a/vcl/README.lifecycle +++ b/vcl/README.lifecycle @@ -45,8 +45,9 @@ to lingering pointers to freed objects. to reduce code-thrash. VclPtr is used to wrap all OutputDevice derived classes thus: - VclPtr<Dialog> pDialog( new Dialog( ... ) ); - // gotcha - this is not a good idea ... + VclPtr<Dialog> pDialog( new Dialog( ... ), SAL_NO_ACQUIRE ); + ... + pDialog.disposeAndClear(); However - while the VclPtr reference count controls the lifecycle of the Dialog object, it is necessary to be able to @@ -84,30 +85,47 @@ to lingering pointers to freed objects. Luckily it is easy to avoid that with a ScopedVclPtr which does this for you when it goes out of scope. +** One extra gotcha - an initial reference-count of 1 + + In the normal world of love and sanity, eg. creating UNO + objects, the objects start with a ref-count of zero. Thus + the first reference is always taken after construction by + the surrounding smart pointer. + + Unfortunately, the existing VCL code is somewhat tortured, + and does a lot of reference and de-reference action on the + class -during- construction. This forces us to construct with + a reference of 1 - and to hand that into the initial smart + pointer with a SAL_NO_ACQUIRE. + + To make this easier, we have 'Instance' template wrappers + that make this apparently easier, by constructing the + pointer for you. + ** How does my familiar code change ? Lets tweak the exemplary code above to fit the new model: -- Dialog aDialog(...); +- Dialog aDialog(... dialog params ... ); - aDialog.Execute(...); -+ ScopedVclPtr<Dialog> pDialog(new Dialog(...)); ++ ScopedVclPtrInstance<Dialog> pDialog(... dialog params ... ); + pDialog->Execute(...); // VclPtr behaves much like a pointer or: -- Dialog *pDialog = new Dialog(...); -+ VclPtr<Dialog> pDialog(newDialog(...)); +- Dialog *pDialog = new Dialog(... dialog params ...); ++ VclPtrInstance<Dialog> pDialog(... dialog params ...); pDialog->Execute(...); - delete pDialog; + pDialog.disposeAndClear(); // done manually - replaces a delete or: -- boost::shared_ptr<Dialog> xDialog(new pDialog()); -+ ScopedVclPtr<Dialog> xDialog(new Dialog(...)); +- boost::shared_ptr<Dialog> xDialog(new Dialog(...)); ++ ScopedVclPtrInstance<Dialog> xDialog(...); xDialog->Execute(...); + // depending how shared_ptr was shared perhaps + // someone else gets a VclPtr to xDialog or: - VirtualDevice aDev; -+ ScopedVclPtr<VirtualDevice> pDev(new VirtualDevice()); ++ ScopedVclPtrInstance<VirtualDevice> pDev(); ** Why are these 'disposeOnce' calls in destructors ? |