Expression ptr->print();
will be implicitly converted to (*ptr).print();
according to C++ Standard (5.2.5/3). And dereferencing the null pointer leads to undefined behaviour. It is fortuitous that the code in question works without errors in your case. You should not rely on it.
5.2.5/3:
If E1 has the type “pointer to class
X,” then the expression E1->E2 is
converted to the equivalent form
(*(E1)).E2; the remainder of 5.2.5
will address only the first option
(dot)59). Abbreviating
objectexpression. id-expression as
E1.E2, then the type and lvalue
properties of this expression are
determined as follows. In the
remainder of 5.2.5, cq represents
either const or the absence of const;
vq represents either volatile or the
absence of volatile. cv represents an
arbitrary set of cv-qualifiers, as
defined in 3.9.3.