It is safe but you should consider providing either a public virtual destructor in zero or a non-virtual protected destructor depending on whether you want to be able to delete objects derived from zero through the base pointer.
Not only is it safe but this is one of the main reasons for inheritance and polymorphism: your zero class provides an interface that is applicable to any type that implements it, regardless of what additional data they store and what additional functionality they provide. Through this shared interface, this multitude of types implementing zero can all be accessed and stored through this common interface that describes the shared aspects of all of them. This is the essence of polymorphism (both static and dynamic) and a very useful means of cutting down redundant code working across related types.