c++methodsconstantsconst-correctness

How to call a non-const method from a const method?


I've got a const method in my class, which cannot be changed to non-const. In this method, I need to call a non-const method but the compiler doesn't let me do that.

Is there any way around it? Here is a simplified sample of my code:

int SomeClass::someMethod() const {
    QColor saveColor = color();
    setColor(QColor(255,255,255)); // Calling non-const method

    // ....

    setColor(saveColor); // restore color

    return 1;
}

Solution

  • One of the challenges of doing const-correctness is you can't do it halfway. It's either all or nothing. If you try to do it halfway, you end up in a tough spot like you are here. You end up with a nice const-correct class being used by some crazy old, typically legacy (or written by an old curmudgeon) code that isn't const-correct and it just doesn't work. You're left wondering if const-correctness is worth all the trouble.

    I need to call a non-const method [from a const method]

    You can't -- not directly. Nor should you. However, there is an alternative...

    Obviously you can't call a non-const method from a const method. Otherwise, const would have no meaning when applied to member functions.

    A const member function can change member variables marked mutable, but you've indicated that this is not possible in your case.

    You could attempt to cast away constness by doing something like SomeClass* me = const_cast<SomeClass*>(this); but A) This will typically result in UB, or 2) It violates the whole idea of const-correctness.

    One thing you could do, if what you're really trying to accomplish would support this, is to create a non-const proxy object, and do nonconst-y stuff with that. To wit:

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Gizmo
    {
    public:
        Gizmo() : n_(42) {};
        void Foo() const;
        void Bar() { cout << "Bar() : " << n_ << "\n"; }
        void SetN(int n) { n_ = n; };
        int GetN() const { return n_; }
    private:
        int n_;
    };
    
    void Gizmo::Foo() const
    {
        // we want to do non-const'y things, so create a proxy...
        Gizmo proxy(*this);
        int save_n = proxy.GetN();
        proxy.SetN(save_n + 1);
        proxy.Bar();
        proxy.SetN(save_n);
    }
    
    int main()
    {
        Gizmo gizmo;
        gizmo.Foo();
    }