C ++防止const方法通过成员指针或引用更改数据

时间:2015-02-26 00:55:51

标签: c++ c++11 const const-correctness

假设我有一个像这样的简单类

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方法),我想要编译错误。

是否有标准解决方案?

我认为某种包装类应该能够实现这一点,并且也应该是编译器优化的东西,尽管没有坐下来试图设计这样的东西来覆盖所有的情况,比如说{ {1}}和strong_const<char*> str(也不确定一个好名字......)。

1 个答案:

答案 0 :(得分:4)

嗯,std::reference_wrapperstd::shared_ptr都不提供常量传播,因此它们不比常规指针更“严格”。

我建议你制作自己的const传播类(我不确定 - 类似的东西已经由boost提供 - 请在评论中告诉我)

我的主张是这堂课:

#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;
};