From c794d08597e6f0c0b54cd70438f3374ccff43201 Mon Sep 17 00:00:00 2001
From: William S Fulton
+The use of %newobject is also integrated with reference counting and is covered in the +C++ reference counted objects section. +
+Compatibility note: Previous versions of SWIG had a special %new directive. However, unlike %newobject, it only applied to the next declaration. For example: diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index fa312c4f1..78e1fbeed 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -38,7 +38,7 @@
-Another usual idiom in C++ is the use of reference counted -objects. Consider for example: - -
-class RCObj {
- // implement the ref counting mechanism
- int add_ref();
- int del_ref();
- int ref_count();
-
-public:
- virtual ~RCObj() = 0;
-
- int ref() const {
- return add_ref();
- }
-
- int unref() const {
- if (ref_count() == 0 || del_ref() == 0 ) {
- delete this;
- return 0;
- }
- return ref_count();
- }
-};
-
-
-class A : RCObj {
-public:
- A();
- int foo();
-};
-
-
-class B {
- A *_a;
-
-public:
- B(A *a) : _a(a) {
- a->ref();
- }
-
- ~B() {
- a->unref();
- }
-};
-
-int main() {
- A *a = new A();
- a->ref(); // 'a' is ref here
-
- B *b1 = new B(a); // 'a' is ref here
- if (1 + 1 == 2) {
- B *b2 = new B(a); // 'a' is ref here
- delete b2; // 'a' is unref, but not deleted
- }
-
- delete b1; // 'a' is unref, but not deleted
- a->unref(); // 'a' is unref and deleted
-}
-
--In the example above, the 'A' class instance 'a' is a reference counted -object, which can't be deleted arbitrarily since it is shared between -the objects 'b1' and 'b2'. 'A' is derived from an Reference Counted -Object 'RCObj', which implements the ref/unref idiom. -
- --To tell SWIG that 'RCObj' and all its derived classes are reference -counted objects, you use the "ref" and "unref" features. -For example: -
- - -
-%module example
-...
-
-%feature("ref") RCObj "$this->ref();"
-%feature("unref") RCObj "$this->unref();"
-
-%include "rcobj.h"
-%include "A.h"
-...
-
--where the code passed to the "ref" and "unref" features will be -executed as needed whenever a new object is passed to python, or when -python tries to release the proxy object instance, respectively. -
- --In the python side, the use of a reference counted object is not -different than any other regular instance: -
- --def create_A(): - a = A() # SWIG ref 'a' (new object is passed to python) - b1 = B(a) # C++ ref 'a' - if 1 + 1 == 2: - b2 = B(a) # C++ ref 'a' - return a # 'b1' and 'b2' are released, C++ unref 'a' twice - -a = create_A() -exit # 'a' is released, SWIG unref 'a' --
-Note that the user doesn't explicitly need to call 'a->ref()' nor 'a->unref()' -(as neither 'delete a'). Instead, SWIG take cares of executing the "ref" -and "unref" codes as needed. If the user doesn't specify the -"ref/unref" features, SWIG will produce a code equivalent to define -them as: -
- -
-%feature("ref") ""
-%feature("unref") "delete $this;"
-
--In other words, SWIG will not do anything special when a new object -is passed to python, and it will always 'delete' the object when -python releases the proxy instance. +The C++ reference counted objects section contains +Python examples of memory management using referencing counting.
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index 97c2e058a..83b9f9da3 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -4618,6 +4618,180 @@ p = f.__deref__() # Raw pointer from operator-> Note: Smart pointer support was first added in SWIG-1.3.14. ++Another similar idiom in C++ is the use of reference counted objects. Consider for example: + +
+class RCObj {
+ // implement the ref counting mechanism
+ int add_ref();
+ int del_ref();
+ int ref_count();
+
+public:
+ virtual ~RCObj() = 0;
+
+ int ref() const {
+ return add_ref();
+ }
+
+ int unref() const {
+ if (ref_count() == 0 || del_ref() == 0 ) {
+ delete this;
+ return 0;
+ }
+ return ref_count();
+ }
+};
+
+
+class A : RCObj {
+public:
+ A();
+ int foo();
+};
+
+
+class B {
+ A *_a;
+
+public:
+ B(A *a) : _a(a) {
+ a->ref();
+ }
+
+ ~B() {
+ a->unref();
+ }
+};
+
+int main() {
+ A *a = new A(); // (count: 0)
+ a->ref(); // 'a' ref here (count: 1)
+
+ B *b1 = new B(a); // 'a' ref here (count: 2)
+ if (1 + 1 == 2) {
+ B *b2 = new B(a); // 'a' ref here (count: 3)
+ delete b2; // 'a' unref, but not deleted (count: 2)
+ }
+
+ delete b1; // 'a' unref, but not deleted (count: 1)
+ a->unref(); // 'a' unref and deleted (count: 0)
+}
+
++In the example above, the 'A' class instance 'a' is a reference counted +object, which can't be deleted arbitrarily since it is shared between +the objects 'b1' and 'b2'. 'A' is derived from a Reference Counted + Object 'RCObj', which implements the ref/unref idiom. +
+ ++To tell SWIG that 'RCObj' and all its derived classes are reference +counted objects, use the "ref" and "unref" features. +These are also available as %refobject and %unrefobject, respectively. +For example: +
+ + +
+%module example
+...
+
+%feature("ref") RCObj "$this->ref();"
+%feature("unref") RCObj "$this->unref();"
+
+%include "rcobj.h"
+%include "A.h"
+...
+
++where the code passed to the "ref" and "unref" features will be +executed as needed whenever a new object is passed to python, or when +python tries to release the proxy object instance, respectively. +
+ ++On the python side, the use of a reference counted object is no +different to any other regular instance: +
+ ++def create_A(): + a = A() # SWIG ref 'a' - new object is passed to python (count: 1) + b1 = B(a) # C++ ref 'a (count: 2) + if 1 + 1 == 2: + b2 = B(a) # C++ ref 'a' (count: 3) + return a # 'b1' and 'b2' are released and deleted, C++ unref 'a' twice (count: 1) + +a = create_A() # (count: 1) +exit # 'a' is released, SWIG unref 'a' called in the destructor wrapper (count: 0) ++
+Note that the user doesn't explicitly need to call 'a->ref()' nor 'a->unref()' +(and neither 'delete a'). Instead, SWIG takes cares of executing the "ref" +and "unref" calls as needed. If the user doesn't specify the +"ref/unref" feature for a type, SWIG will produce code equivalent to defining these +features: +
+ +
+%feature("ref") ""
+%feature("unref") "delete $this;"
+
++In other words, SWIG will not do anything special when a new object +is passed to python, and it will always 'delete' the underlying object when +python releases the proxy instance. +
+ ++
+ ++The %newobject feature is designed to indicate to +the target language that it should take ownership of the returned object. +When used in conjunction with a type that has the "ref" feature associated with it, it additionally emits the +code in the "ref" feature into the C++ wrapper. +Consider wrapping the following factory function in addition to the above: +
+ +
+%newobject AFactory;
+A *AFactory() {
+ return new A();
+}
+
++The AFactory function now acts much like a call to the A constructor with respect to memory handling: +
+ ++a = AFactory() # SWIG ref 'a' due to %newobject (count: 1) +exit # 'a' is released, SWIG unref 'a' called in the destructor wrapper (count: 0) ++