# HG changeset patch
# User Robert Bradshaw <robertwb@gmail.com>
# Date 1458881246 25200
#      Thu Mar 24 21:47:26 2016 -0700
# Node ID e7209d64ef2c23d83b6cf63436de18c0c677b777
# Parent  9bb933bd3affa3e392a54c95c72ed0eab04d5fa0
Update C++ Rectangle example.

diff --git a/docs/src/userguide/wrapping_CPlusPlus.rst b/docs/src/userguide/wrapping_CPlusPlus.rst
--- a/docs/src/userguide/wrapping_CPlusPlus.rst
+++ b/docs/src/userguide/wrapping_CPlusPlus.rst
@@ -48,11 +48,11 @@
         class Rectangle {
         public:
             int x0, y0, x1, y1;
+            Rectangle();
             Rectangle(int x0, int y0, int x1, int y1);
             ~Rectangle();
-            int getLength();
-            int getHeight();
             int getArea();
+            void getSize(int* width, int* height)
             void move(int dx, int dy);
         };
     }
@@ -65,6 +65,8 @@
 
     namespace shapes {
 
+      Rectangle::Rectangle() { }
+
         Rectangle::Rectangle(int X0, int Y0, int X1, int Y1) {
             x0 = X0;
             y0 = Y0;
@@ -74,16 +76,13 @@
 
         Rectangle::~Rectangle() { }
 
-        int Rectangle::getLength() {
-            return (x1 - x0);
+        int Rectangle::getArea() {
+            return (x1 - x0) * (y1 - y0);
         }
 
-        int Rectangle::getHeight() {
-            return (y1 - y0);
-        }
-
-        int Rectangle::getArea() {
-            return (x1 - x0) * (y1 - y0);
+        void Rectangle::getSize(int *width, int *height) {
+            width = x1 - x0;
+            height = y1 - y0;
         }
 
         void Rectangle::move(int dx, int dy) {
@@ -192,11 +191,11 @@
 
     cdef extern from "Rectangle.h" namespace "shapes":
         cdef cppclass Rectangle:
+            Rectangle() except +
             Rectangle(int, int, int, int) except +
             int x0, y0, x1, y1
-            int getLength()
-            int getHeight()
             int getArea()
+            void getSize(int* width, int* height)
             void move(int, int)
 
 Note that the constructor is declared as "except +".  If the C++ code or
@@ -229,7 +228,7 @@
         ...
 
 Note that, like C++, if the class has only one constructor and it
-is a default one, it's not necessary to declare it.
+is a nullary one, it's not necessary to declare it.
 
 Create Cython wrapper class
 ----------------------------
@@ -239,33 +238,53 @@
 external Python code (which is our whole point).
 
 Common programming practice is to create a Cython extension type which
-holds a C++ instance pointer as an attribute ``thisptr``, and create a bunch of
+holds a C++ instance as an attribute and create a bunch of
 forwarding methods. So we can implement the Python extension type as::
 
     cdef class PyRectangle:
-        cdef Rectangle *thisptr      # hold a C++ instance which we're wrapping
+        cdef Rectangle c_rect      # hold a C++ instance which we're wrapping
         def __cinit__(self, int x0, int y0, int x1, int y1):
-            self.thisptr = new Rectangle(x0, y0, x1, y1)
-        def __dealloc__(self):
-            del self.thisptr
-        def getLength(self):
-            return self.thisptr.getLength()
-        def getHeight(self):
-            return self.thisptr.getHeight()
-        def getArea(self):
-            return self.thisptr.getArea()
+            self.c_rect = Rectangle(x0, y0, x1, y1)
+        def get_area(self):
+            return self.c_rect.getArea()
+        def get_size(self)
+            int width, int height
+            self.c_rect.getSize(&width, &height)
+            return width, height
         def move(self, dx, dy):
-            self.thisptr.move(dx, dy)
+            self.c_rect.move(dx, dy)
 
 And there we have it. From a Python perspective, this extension type will look
-and feel just like a natively defined Rectangle class. If you want to give
+and feel just like a natively defined Rectangle class.
+It should be noted that
+
+If you want to give
 attribute access, you could just implement some properties::
 
-    property x0:
-        def __get__(self): return self.thisptr.x0
-        def __set__(self, x0): self.thisptr.x0 = x0
+    @property
+    def x0(self):
+        return self.c_rect.x0
+
+    @x0.setter
+    def x0(self):
+        def __set__(self, x0): self.c_rect.x0 = x0
     ...
 
+Cython initializes C++ class attributes of a cdef class using the nullary constructor.
+If the class you're wrapping does not have a nullary constructor, you must store a pointer
+to the wrapped class and manually allocate and deallocate it.
+A convienient and safe place to do so is in the `__cinit__` and `__dealloc__` methods
+which are guaranteed to be called exactly once upon creation and deletion of the Python
+instance.
+
+    cdef class PyRectangle:
+        cdef Rectangle* c_rect      # hold a pointer to the C++ instance which we're wrapping
+        def __cinit__(self, int x0, int y0, int x1, int y1):
+            self.c_rect = new Rectangle(x0, y0, x1, y1)
+        def __dealloc__(self):
+            del self.c_rect
+        ...
+
 If you prefer giving the same name to the wrapper as the C++ class, see the
 section on :ref:`resolving naming conflicts <resolve-conflicts>`.