Constness of returned object (s) from const member function

What is a good rule of thumb as to whether or not the return value of a constant member function should be const or not? Here is what I am doing, but I am struggling with ambiguous scenarios.

class foo
{
    public:
        // if the returned object is conceptually
        // (and therefore usually literally but not even necessarily) 
        // owned by *this*,
        // then a const ptr should be returned
        const ownedByFoo *getOwnedByFoo() const { return m_ownedByFoo; }
        ownedByFoo *getOwnedByFoo() { return m_ownedByFoo; }

        // what a poor boy to do here?
        // veryRelatedToFoo might be a conceptual contemporary or parent
        // of Foo. Note naming the function "find..." instead of "get.."
        // since *get* implies the object holds it as a data member but
        // that may not even be the case here. There could be a
        // standalone container that associates foo and veryRelatedToFoo.
        // Should constness be symmetrical here?
        const veryRelatedToFoo *findVeryRelatedToFoo() const;
        veryRelatedToFoo *findVeryRelatedToFoo();

        // If the returned object is only (conceptually)
        // peripherally related to *this*, 
        // the returned object probably shoudn't be const, even if
        // foo happens to have one of these as a direct data member,
        // since we don't want to give away the implementation details of
        // Foo and it may hold peripherallyRelatedToFoo simply for performance
        // reasons, etc.
        peripherallyRelatedToFoo *findPeripherallyRelatedToFoo() const

    ...
};

      

Another note is that once you have an asymmetric constant, you can ask const A to return B, then ask B to return A, and then you managed to get around the supposed constant of A.

+1


a source to share


5 answers


Having a constant of some kind is more than you will find in many languages!

Once you understand (as you do) the difference between "physically const" and "logically const", then the "ambiguous" scenarios are still negotiable. Consider, for example, the fact that a keyword exists mutable

.



I think that you have the right general idea: why is it all controversial and subjective and varies depending on the specific problem and restrictions, etc.

I prefer "exceptions to the rule", so I would not return a non-const pointer from a const method; but I guess I can imagine some scenarios in which I might be tempted ... although I might rather make the way non-const instead.

+1


a source


(I ignore the fact that you are returning the state of an object directly like this, which is usually bad because it breaks encapsulation - I see this as "sample code")

There is no connection between them. A const

member function is a member that does not modify the underlying object "at runtime". There are no promises or requirements for the return value to be const

or not. The contract is const

-ness "over" as soon as the method returns. I think you are confused because you are trying to wire the return value using the method that created it.

The return value should const

or should not const

depend solely on the nature of the return value and the semantics you want to assign to this method.



In your specific first case, the two methods should return the same const

-ness. Constant overloading is probably not what you want to use. If you want two options, I would probably make it explicit, like this:

const ownedByFoo *getOwnedByFoo() const { return m_ownedByFoo; }
ownedByFoo *getOwnedByFooForEdit() { return m_ownedByFoo; }

      

Thus, there is no ambiguity and mysterious connection between the two. Note that I made the second non-const one because we probably don't want the client code to change m_ownedByFoo for the const object. This requirement stems from the semantics of the method ("returns internal state"), not from the relationship between the const

-ness method and the const

-ness return value. If the return value was not part of the object's state, I would probably do something else.

+1


a source


Do not return a non-content pointer or member data reference from a const method.

0


a source


If the returned reference is const, then make the function const, if it isn't. You should try to avoid returning a non-const reference to the element's data, albeit because it breaks encapsulation, unless the class is the main view of the container class.

0


a source


If returning a non-const reference / pointer would allow the caller to invalidate an invariant that the class should support, then don't return that non-const reference / pointer. (It must be const.)

0


a source







All Articles