c++const-correctness

In C++, is a const method returning a pointer to a non-const object considered bad practice?


In C++, is a const method returning a pointer to a non-const object considered bad practice? For example. consider the following methods:

// Makes perfect sense
bool isActive() const { return m_isActive; }

// Makes perfect sense, both consts ensure nothing is modified
const SomeObject* someObject() const { return m_someObject; }

// Makes perfect sense, no const because SomeObject is mutable,
// thus MyClass is indirectly mutable
SomeObject* someObject() { return m_someObject; }

// Makes no sense, if you're just returning a pointer to a const object,
// then the method should clearly be const since nothing can be modified
const SomeObject* someObject() { return m_someObject; }

The last combination puzzles me: is the following considered bad practice?

SomeObject* someObject() const { return m_someObject; }

Because the class that method returns is not const, but the method is, it is somewhat pointless since you could modify SomeObject and thus indirectly modify your class... so is that form considered bad practice? e.g. should you only use one of the following in place of it?

const SomeObject* someObject() const { return m_someObject; }
SomeObject* someObject() { return m_someObject; }

Real-world situation: I'm writing a smartphone game which has a Game class. The Game class contains several methods which return pointers to utility classes like InputManager, AudioManager, etc.

class Game
{
public:
    InputManager* inputManager() const { return m_inputManager; }
    ...

private:
    InputManager* m_inputManager;
    ...
}

Does it make ANY sense at all to make inputManager() const, since the object it returns is not? (and should not be, since the InputManager needs to be mutable for its state to be updated, etc.)

Or should I remove the method's const modifier to more accurately reflect the method's behavior? That way if I had a const Game, I couldn't call inputManager() and then mess with the Game's input manager even though the Game was const.


Solution

  • It depends on whether the non-const pointer is pointing to something inside the const object, or whether it is newly allocated memory that is meant to be variable.

    Consider something that returned a copy of a string; it's fine for the returned copy to be non-const, even if the original string is const. The ownership of the copy is being passed from the method to the calling code; ensuring that the copy is appropriately destructed is now the calling code's problem (quite possibly a very minor problem).

    However, it would be a very bad idea to return a non-const pointer to something from inside a const object.