C++ Preventing const methods from changing data through a member pointer or reference

c++, c++11, const-correctness, constants

Solution

Well, neither `std::reference_wrapper` nor `std::shared_ptr` do not provide const propagation, so they are not more "const-strict" than regular pointer.

I'd recommend to make your own const propagation class (I am not sure - maybe something similar is already provided by boost - please let me know in comments)

My proposition is this class:

#include <memory> // for pointer_traits

template <typename Pointer>
class ConstPropagatePointer 
{
public:
    using element_type = typename std::pointer_traits<Pointer>::element_type;
    using pointer = typename std::pointer_traits<Pointer>::pointer;
    using const_pointer = element_type const * const;
    using reference = element_type&;
    using const_reference = element_type const&;

    ConstPropagatePointer(Pointer ptr) : ptr(ptr) {}
    pointer operator -> ()
    {
        return &(*ptr);
    }
    const_pointer operator -> () const
    {
        return &(*ptr);
    }
    reference operator * ()
    {
        return *ptr;
    }
    const_reference operator * () const 
    {
        return *ptr;
    }
private:
    Pointer ptr;
};

So that will work for you:

class Foo
{
public:
private:
    ConstPropagatedPointer<char*> str; 
    ConstPropagatedPointer<ComplexObj*> obj; 
    ConstPropagatedPointer<std::shared_ptr<ComplexObj>> obj2;
};

Problem

Say I have a simple class like this ``` class Foo { public: void foo()const { str[5] = 'x'; obj->changeTheWorld(); x = 4; y.get() = 5; obj2->changeTheWorld(); } private: char *str; //some referenced data, not owned by Foo ComplexObj *obj; //some referenced data, not owned by Foo int &x; //references as well //wrapped reference, but has a "T& get()const" std::reference_wrapper<int> y; //an occasionally useful pointer wrapper for complex memory cases //but has a "T* get()const" std::shared_ptr<ComplexObj> obj2; }; ``` This is valid because in the const method, its just the pointer itself that becomes const, not the data it points to. However in many cases that is not what I desired and I want a compile error if a const method tries to change these members contents (either directly or by calling a non-const method on that member). Is there a standard solution to this? I think some kind of wrapper class should be able to achieve this, and should also be something the compiler optimises out, although haven't sat down to try and design such a thing to cover all cases giving say a `strong_const<char*> str` and `strong_const<int&>` (also not sure on a good name...).

Original source

Related problems