C++ object lifetime, ownership, classes and polymorphism
Separate objects from access paths
A pointer can designate an object, but the pointer itself does not prove that the object is alive or accessible. Dereferencing a null, invalid or dangling pointer is not a valid way to inspect a value. An array expression often converts to a pointer to its first element, but the array and pointer are different types and do not have identical size or lifetime properties. Pointer arithmetic must remain within the permitted array boundaries; a one-past pointer is not an element to dereference.
Make ownership explicit
Match the correct allocation and deallocation form, including the array form when applicable. Resource acquisition is initialization ties an owned resource to an object’s lifetime and supports cleanup on ordinary scope exit and appropriate exception unwinding. Prefer suitable standard-library ownership and container types rather than duplicating raw ownership without a rule. A smart pointer is not a guarantee that arbitrary cycles, borrowed references or external-resource protocols are correct. Destruction and release still depend on the actual ownership arrangement.
Trace construction and access
Constructors establish the object’s state; destructors perform its relevant cleanup. Base subobjects and members have specified initialization/destruction relationships rather than simply following any visually convenient initializer order. Class members are private by default, while struct members are public by default. Public, protected and private access control where names can be used; they do not encrypt memory. Namespaces organize names and help avoid collisions without providing process isolation or a security boundary.
Respect dynamic-type rules
A virtual function supports dispatch through an appropriate base pointer or reference. Hiding a nonvirtual member is different from overriding a virtual one. For the usual polymorphic deletion case, deleting a derived object through a base pointer requires the appropriate virtual destructor; an apparently correct printed value before invalid deletion does not make the whole program defined. Calls during construction/destruction have their own dynamic-type rules. Pure virtual declarations can have separate definitions in permitted forms, so abstract does not simply mean every such function lacks all implementation. These written examples teach bounded language reasoning and perform no production memory inspection or software deployment.