I use the following method prefixes to denote object ownership.
Ownership implies responsibility for deletion.
Y.take_ZZZ(x)
The caller is giving ownership of x to Y and caller must not further access x.
(because Y could even immediately delete x).
Y.own_ZZZ(x)
Similar to take;
the caller is giving ownership of x to Y but caller may continue to reference x
and expect Y will not immediately delete x
(at least as long a Y exists and it is assumed that Y will exist at least throughout the context of the caller knowing of Y).
Usually Y will not delete x until Y is destroyed (although Y may transfer ownership).
Y.know_ZZZ(x)
The caller is providing a pointer/reference to x (the caller may or may not itself own x), but Y is not to take ownership of x.
Y will expect that x will exist as long as it does.
x = Y.provide_ZZZ()
x is an object that Y owns.
Y returns a reference (&) to the object so the caller can 'know' it.
The object it may be initially a null pointer until it is required, Y may not create the object until it is needed.
Whether x is dynamically allocated or not is hidden from the caller, Y does whatever is needed to return the reference to an instances of the object to be provided.
x will then remain instantiated as long as Y exists.
Sometimes I will provided a corresponding method Y.done_with_ZZZ(x) so that the caller can tell Y it is done can delete x.
x = Y.give_ZZZ()
Y relinquishes x to the caller and will no further reference it.
The caller will then own x and be responsible for deleting it or giving it to another object.
x = Y.lend_ZZZ()
Y provides a reference/pointer to x to the caller (opposite of know_ZZZ)
Y retains ownership.
(similar to provide, but Y does not instantiate X, so it will either have x and return the reference(pointer) or it will not and return null.
x = Y.check_out_ZZZ() and Y.check_in_ZZZ(x)
With checkout, Y gives the caller exclusive access to x until the caller checks it in.
x = Y.create_ZZZ()
Y will create x and immediately relinquish it to the caller (factory function).
The ownership can be further strengthened by using smart pointers,
but generally I use these naming conventions without smart pointers unless
there is going to be a more complicated sequence of ownership transactions, the scope of ownership is not very localized, or the objects are going to be referenced (known) by multiple objects.