C ++防止const方法通过成员指针或引用更改数据 [英] C++ Preventing const methods from changing data through a member pointer or reference
问题描述
说我有一个像这样的简单班级
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;
};
这是有效的,因为在const方法中,它只是变成const的指针本身,而不是数据它指向。但是,在很多情况下,这不是我想要的,并且如果const方法尝试更改这些成员的内容(直接更改或通过对该成员调用非const方法),则我希望编译错误。
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?
我认为某种包装器类应该能够实现这一目标,并且应该是编译器会进行优化,尽管还没有坐下来尝试设计这样的东西来涵盖所有情况,例如说 strong_const< char *> str
和 strong_const< int&>
(也不确定好名字...)。
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...).
推荐答案
好, std :: reference_wrapper
和 std :: shared_ptr
不提供const传播,因此它们不比常规指针更 const-strict。
Well, neither std::reference_wrapper
nor std::shared_ptr
do not provide const propagation, so they are not more "const-strict" than regular pointer.
我建议创建自己的const传播类(我不确定-boost可能已经提供了类似的东西-请在评论中让我知道)
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)
我的主张是此类:
#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;
};
这样对您有用:
class Foo
{
public:
private:
ConstPropagatedPointer<char*> str;
ConstPropagatedPointer<ComplexObj*> obj;
ConstPropagatedPointer<std::shared_ptr<ComplexObj>> obj2;
};
这篇关于C ++防止const方法通过成员指针或引用更改数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!