2.4.1 Design philosophy of the classes
See also section 2.4.3.
The general philosophy for C++ classes is that a "half-created" object should not be possible - that is, the constructor should either succeed with a completely usable object or it should throw an exception. This API tries to follow that philosophy, but there are some important exceptions and caveats. (For more on how the C++ and Prolog exceptions interrelate, see section 2.16.)
The various classes (PlAtom
, PlTerm
, etc.)
are thin wrappers around the C interface's types (atom_t
,
term_t
, etc.). As such they inherit the concept of "null"
from these types (which is abstracted as PlAtom::null
,
PlTerm::null
, etc., which typically is equivalent to
0
). You can check whether the object is "fully created" by
using the verify() method - it will throw an exception if the
object is null
.
However, most of the classes have constructors that create a "complete" object. For example,
PlAtom foo("foo");
will ensure that the object foo
is useable and will
throw an exception if the atom can't be created.
To help avoid programming errors, most of the classes do not have a
default "empty" constructor. For example, if you with to create a
PlAtom
that is uninitialized, you must explicitly use
PlAtom(PlAtom::null)
. This make some code a bit more
cumbersome because you can't omit the default constructors in struct
initalizers.
Many of the classes wrap long-lived items, such as atoms, functors,
predicates, or modules. For these, it's often a good idea to define them
as static
variables that get created at load time, so that
a lookup for each use isn't needed (atoms are unique, so
PlAtom("foo")
requires a lookup for an atom foo
and creates one if it isn't found). Sometimes, it's desirable to create
them "lazily", such as:
static PlAtom foo(PlAtom::null}; ... if ( foo.is_null() ) foo = PlAtom("foo");
The class PlTerm
(which wraps term_t
) is
the most used. Although a PlTerm
object can be created from
a term_t
value, it is intended to be used with a
constructor that gives it an initial value. The default constructor
calls PL_new_term_ref() and throws an exception if this fails.
The various constructors are described in
section 2.9.1. Note that the
default constructor is not public; to create a "variable" term, you
should use the subclass constructor PlTerm_var().