Using primitive data types to represent domain ideas is code smell called Primitive Obsession. For example using string data type to represent human name - it is recomended to avoid this by defining domain specific value object with apropriate methods.
But what about pointers?
Is it not primitive obsession to use CItem* or shared_ptr instead of more domain specific types like CItemHandle, CItemLink etc. ?
My viewpoint with this question is that usefulness of type is not only about what behaviors it allows, but also about what behavior it don't allows. Primitive type gives you some set of constraints. User defined types can give you different set of constraints. Thanks to this, user defined type can clearly model domain by using domain constraint and domaing wording in its interface and this also helps with promoting right thinking and in result right decision when making changes in system. User defined type which encapsulates pointer simply gives you more precisse control than pointer itself to enforce proper use of it.