summaryrefslogtreecommitdiff
path: root/vcl/README.lifecycle
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-03-30 17:49:20 +0100
committerMichael Meeks <michael.meeks@collabora.com>2015-04-10 13:13:53 +0100
commit582e89610b366c0d887baa6b8de7fa5f065900fa (patch)
tree91f3b723d1485b5616d457e30011fa55914785a4 /vcl/README.lifecycle
parent49dadad0b55f879ebe5daf539a97043d283ad0a8 (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.lifecycle36
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 ?