C ++防止const方法通过成员指针或引用更改数据 [英] C++ Preventing const methods from changing data through a member pointer or reference

查看:81
本文介绍了C ++防止const方法通过成员指针或引用更改数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个像这样的简单班级

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆