是否可以仅为const操作指定一个私有成员变量public?

时间:2014-10-31 17:13:23

标签: c++ c++11 const member-variables

我有一个成员变量enabled_m,其值取决于许多变量。由于这些不变量应该由类维护,我希望它是private

class foo_t
{
public:
    void set_this(...); // may affect enabled_m
    void set_that(...); // may affect enabled_m
    void set_the_other_thing(...); // may affect enabled_m

    bool is_enabled() const { return enabled_m; }

private:
    bool enabled_m;
};

哪个有效,但我的意图是要求foo_t的用户通过课程修改 enabled_m。如果用户想要读取 enabled_m,那应该是允许的操作:

bool my_enabled = foo.enabled_m; // OK
foo.enabled_m = my_enabled; // Error: enabled_m is private

是否可以为enabled_m操作public const和非private操作const,无需用户通过访问器例程?

3 个答案:

答案 0 :(得分:10)

大多数工程师都希望你使用访问器方法,但如果你真的想要一个hack-around,你可以这样做:

class AccessControl
{
private:
    int dontModifyMeBro;
public:
    const int& rDontModifyMeBro;
    AccessControl(int theInt): dontModifyMeBro(theInt), rDontModifyMeBro(dontModifyMeBro)
    {}

    // The default copy constructor would give a reference to the wrong variable.
    // Either delete it, or provide a correct version.
    AccessControl(AccessControl const & other): 
        dontModifyMeBro(other.rDontModifyMeBro), 
        rDontModifyMeBro(dontModifyMeBro)
    {}

    // The reference member deletes the default assignment operator.
    // Either leave it deleted, or provide a correct version.
    AccessControl & operator=(AccessControl const & other) {
        dontModifyMeBro = other.dontModifyMeBro;
    }
};

答案 1 :(得分:9)

不,没有办法只限制成员修改。 private限制对该名称的所有访问权限; const阻止在任何地方进行修改。

有一些奇怪的替代方案(如const引用或const_cast的使用),但访问器功能是最简单,最惯用的方法。如果它是内联的,如在您的示例中那么,它的使用应该与直接访问一样有效。

答案 2 :(得分:5)

这里很大程度上取决于暴露启用状态背后的意图,我的一般建议是避免将其暴露

is_enabled的通常用途如下:

if (f.is_enabled())
    f.set_this(whatever);

在我看来,调用set_this几乎总是更好,并且(如果客户端关心)让它返回一个值来指示是否成功,所以客户端代码变成如下:

if (!f.set_this(whatever))
   // deal with error

虽然当你开始进行多线程编程时,这似乎是一个微不足道的差异(对于一个主要的例子),差异变得绝对至关重要。特别是,测试启用状态,然后尝试设置值的第一个代码受竞争条件限制 - enabled状态可能在调用is_enabled和调用{{set_this之间发生变化1}}。

长话短说,这通常是一个糟糕的设计。只是不要这样做。