Click here to Skip to main content
15,884,472 members
Articles / Programming Languages / C++
Tip/Trick

C++ Tip: Modification Inside const Function

Rate me:
Please Sign up or sign in to vote.
3.03/5 (6 votes)
10 Dec 2017CPOL 14.8K   58   2   6
Modification inside const member function

Introduction

There are times where modification inside const member function must be done (for example, to allow for caching or memoization). The mutable keyword and const_cast are well-known in the C++ circles to work around these. The 3rd way is to use a const pointer; we cannot modify the const pointer but we can modify the contents it pointed to. Let's dive in and discover for ourselves.

mutable Keyword

We will do a quick recap on the mutable keyword. A lock have to be acquired on mutex. So by declaring the mutex mutable, it can be used inside a const function.

C++
class MyClass1
{
public:
    MyClass1(int value) : m_Value(value) {}

    int GetValue() const
    {
        std::lock_guard<std::mutex> lock(m_Mutex);
        return m_Value;
    }
private:
    int m_Value;
    mutable std::mutex m_Mutex;
};

int GetValue(const MyClass1& c)
{
    return c.GetValue();
}

Cast Away Constness

Next example, we will declare the member function as non-const and do a const_cast(). Typically C++ developers who do not know the mutable keyword will use this technique.

C++
class MyClass2
{
public:
    MyClass2(int value) : m_Value(value) {}

    int GetValue() // not const
    {
        std::lock_guard<std::mutex> lock(m_Mutex);
        return m_Value;
    }
private:
    int m_Value;
    std::mutex m_Mutex;
};
int GetValue(const MyClass2& c)
{
    MyClass2& c2 = const_cast<MyClass2&>(c); // cast away the constness
    return c2.GetValue();
}

Const Pointer to Member

As advertised, the data member can be modified though the member pointer.

C++
class MyClass3
{
public:
    MyClass3(int value) : m_Value(value), m_pMutex(&m_Mutex) {}

    int GetValue() const
    {
        std::lock_guard<std::mutex> lock(*m_pMutex);
        return m_Value;
    }
private:
    int m_Value;
    std::mutex m_Mutex;
    std::mutex* m_pMutex;
};
int GetValue(const MyClass3& c)
{
    return c.GetValue();
}

Local Pointer to Member Does Not Compile

If local pointer is used, compiler will complain "error C2440: 'initializing': cannot convert from 'const std::mutex *' to 'std::mutex *'".

C++
// cannot work.
class MyClass4
{
public:
    MyClass4(int value) : m_Value(value) {}

    int GetValue() const
    {
        std::mutex* pMutex = &m_Mutex; // compiler complain
        std::lock_guard<std::mutex> lock(*pMutex);
        return m_Value;
    }
private:
    int m_Value;
    std::mutex m_Mutex;
};
int GetValue(const MyClass4& c)
{
    return c.GetValue();
}

unique_ptr

Instead of raw pointer, using unique_ptr works as well.

C++
class MyClass5
{
public:
    MyClass5(int value) : m_Value(value), m_pMutex(std::make_unique<std::mutex>()) {}

    int GetValue() const
    {
        std::lock_guard<std::mutex> lock(*m_pMutex);
        return m_Value;
    }
private:
    int m_Value;
    std::unique_ptr<std::mutex> m_pMutex;
};
int GetValue(const MyClass5& c)
{
    return c.GetValue();
}

The example code is hosted at Github.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Singapore Singapore
Shao Voon is from Singapore. His interest lies primarily in computer graphics, software optimization, concurrency, security, and Agile methodologies.

In recent years, he shifted focus to software safety research. His hobby is writing a free C++ DirectX photo slideshow application which can be viewed here.

Comments and Discussions

 
Generalvery good summary Pin
Southmountain21-Jan-20 3:18
Southmountain21-Jan-20 3:18 
Question[My vote of 1] ??? Pin
jefito11-Dec-17 16:46
jefito11-Dec-17 16:46 
AnswerRe: [My vote of 1] ??? Pin
Shao Voon Wong11-Dec-17 21:37
mvaShao Voon Wong11-Dec-17 21:37 
QuestionYou have missed the point Pin
Michael Chourdakis11-Dec-17 11:58
mvaMichael Chourdakis11-Dec-17 11:58 
AnswerRe: You have missed the point Pin
Shao Voon Wong11-Dec-17 21:41
mvaShao Voon Wong11-Dec-17 21:41 
GeneralRe: You have missed the point Pin
Stefan_Lang8-Jan-18 4:20
Stefan_Lang8-Jan-18 4:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.