Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Member functions that are sometimes const

Tags:

c++

constants

I have a class design similar to the following:

class MyClass {
public:
    bool IsValid() const;
    void MakeValid();
private:
    bool CheckValidity(bool fix);
};

bool MyClass::IsValid() const {
    // Check validity, but don't fix any problems found.  Doesn't work.
    return CheckValidity(false);
}

void MyClass::MakeValid() {
    // Check validity and fix problems found.
    CheckValidity(true);
}

IsValid should be const, because it doesn't make changes. MakeValid should be non-const, because it does make changes. They share the same implementation, CheckValidity, but because CheckValidity may or may not make changes, it can't be marked const.

What's the best way to handle this? The simplest approach is to just use const_cast, but casting away const feels a bit dirty:

bool MyClass::IsValid() const {
    // Check validity, but don't fix any problems found.
    return const_cast<MyClass*>(this)->CheckValidity(false);
}

Is this a legitimate use of const_cast? Is there a better approach?

like image 454
Josh Kelley Avatar asked Mar 13 '15 15:03

Josh Kelley


People also ask

Can a member function be const?

Const member functions in C++ Like member functions and member function arguments, the objects of a class can also be declared as const. an object declared as const cannot be modified and hence, can invoke only const member functions as these functions ensure not to modify the object.

What are const member functions option?

A const member function is a member function that guarantees it will not modify the object or call any non-const member functions (as they may modify the object).

When a member function is declared as const it means that?

Declaring a member function with the const keyword specifies that the function is a "read-only" function that doesn't modify the object for which it's called. A constant member function can't modify any non-static data members or call any member functions that aren't constant.

Which member functions should be const in a class data type and why?

As a general rule: Any non- static member function that does not modify the data members of the object that called it should be declared to be const . That way it will work with constant objects.


1 Answers

I'm assuming your implementation looks similar to this:

bool CheckValidity(bool fix)
{
    // Actually check validity.
    bool isValid = ...;

    if (!isValid && fix)
    {
        // Attempt to fix validity (and update isValid).
        isValid = ...;
    }

    return isValid;
}

You really have two different functions shoved into one. One of the key indicators of this kind of entanglement is the boolean argument to the function... which smells because the caller cannot immediately discern whether to put true or false without referencing code/docs.

Split up the method:

bool CheckValidity() const
{
    // Actually check validity.
    bool isValid = ...;
    return isValid;
}

void FixValidity()
{
    // Attempt to fix validity.
    // ...
}

And then your public methods can make the calls more appropriately.

bool IsValid() const
{
    // No problem: const method calling const method
    return CheckValidity();
}

void MakeValid()
{
    if (!CheckValidity())  // No problem: non-const calling const
    {
         FixValidity();    // No problem: non-const calling non-const
    }
}
like image 104
Matthew Moss Avatar answered Nov 04 '22 10:11

Matthew Moss