This chapter delves into the construction of
Python and C++ objects. This is a complex topic, and not really
required if you are only interested in getting started with your
project. However, when you feel that your objects are disappearing
from under your hands, or if you're leaking memory like a sieve,
then this is the place to turn to.
Pointers and references
In order to be able to determine the
relations between Python objects and C++ objects it is necessary
to first gain a good understanding of what
an object is, exactly, and what constitutes a reference to an
object.
In C++, an object is simply a chunk of
memory that contains executable bytes and data bytes. The
executable bytes represent the functions, and the data bytes
represent the values of the object variables. Of course, this is
a simplified representation: the functions are shared by all
objects of the same class, and there is some serious (and
platform dependent) pointer logic needed to find them. But,
basically, a C++ object is simply a stretch of memory that has
to be allocated explicitly by the developer (using
new()), and also deallocated explicitly by
the developer, with delete().
The object can be accessed by other parts of
the application as long as its location in memory is known: the
variable that contains the location is a pointer. If a
programmer knows the size of an object, he can do fancy things
(such as loop through the memory by adding the size of the
object to the pointer) to get at the location of the next
object.
However, once the pointer variable is lost,
there's no longer a certain way of getting at the location of
the object, and there's no way to delete the object—the
memory will remain occupied for as long as the application runs,
and there's no way it can be useful! This
is called a memory leak, and is undoubtedly a bad thing.
One of the strengths of Python is that the
programmer is freed of the responsibility of explicitly deleting
objects. Python manages all objects for you. It does this by
keeping track of references to every
object. A reference is a variable, or an entry in a list that
represents an object. For instance, run:
Example 9-1. refs.py - showing object references
#
# refs.py
#
class theClass: pass
anObject=theClass()
aList=[anObject]
aDictionary={"key": anObject}
print anObject
print aList
print aDictionary
This will result in one object with three references, as you
can see from the result of the print
statements:
<__main__.theClass instance at 0x81d9cb4>
[<__main__.theClass instance at 0x81d9cb4>]
{'key': <__main__.theClass instance at 0x81d9cb4>}
The object instance (0x81dcb4 is the object's id hash) will
only be deleted when the last reference is deleted. It is
possible for references to disappear by going out of scope. If
the references are created inside a function, then as soon as
the function is finished running, the references disappear.
References to variables can also be attached to both classes (a
class is an object in Python), and to objects. In the first
case, if the class disappears, then the references disappear. In
the second case, if the last reference to the object disappears,
all references that object ‘has' to other objects disappear,
too.