P197 [[nitty gritty]] points out that at compile time and/or runtime, “system” knows the type of each ptr object. One exception is the void ptr, whose type is undefined.
“Pointer object” means the 4-byte ptr object. This object could be a field of a class object; or a stackVar, or a global var.
Obviously as a pointer this variable holds an address. This address should be another object. The type of the pointee object is the type of the pointer. System remembers each pointer’s type. That’s why pointer cast is a controlled operation. A compiler need this type information to allocate memory.
What if the pointee is a derived object? See the post on AOB (ie address of basement).
In conclusion, a ptr object
* has an address of its own
* holds an address unless it’s a null or uninitialized pointer
* has a type unless it’s a void ptr
* has a name ie the variable name
* has an optional pointee-name — qq(Cat * cptr = &myCat; ). Pointee could be on heap or stack. If it’s on heap, the pointee object is always nameless but myCat could be a name attached to it subsequently.
 if dangling, then the pointee could be another stackframe, or any used/unused heap address.