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...).