2

C++ 中有没有办法强制在类中使用 getter 或 setter?

class C{
   private:
   int x;        // should only be Changed by setX();

   private:
   setX(int i){
       (...)     // enforce some complicated invariantes
       x = i;
   };

   m(){
      x = 5;     // should not not allowed
   }
}

我唯一想到的是将所有超级私有成员作为私有变量放入具有受保护的 getter/setter 的抽象基类中。

但这听起来不是好的做法。

有没有更常见的方法或约定来确保每个人都使用设置器?

(我的目的:如果类变得更大,我发现很难记住哪些变量带有不变量。目前在设置我搜索的任何变量之前,我是否创建了一个 getter 或 setter(以确定我是否必须考虑不变量)。但我想每次都摆脱这种不专业的搜索。)

4

4 回答 4

3

您可以利用这样的组合:

class C_int
{
public:
    void setX(int i)
    {
        /* enforce invariants */
        x = i;
    }

private:
    int x;
};

class C
{
pulbic:
    void m()
    {
        x.setX(5);
        // x.x = 5; // Won't compile.
    }

private:
    C_int x;
};

但我觉得奇怪的是,这对你来说是一个实际的问题,恕我直言。你是C班级及其成员的作者。您可以控制x变量的读取/写入方式,并且x它不是类的公共接口的一部分。虽然其他人(例如维护人员)确实可以编写将来破坏不变量的代码,但单元测试应该能够涵盖这些情况。

于 2011-08-25T08:19:54.517 回答
1

a) 在整个代码库中支持访问器以保持一致性。那么您将更容易发现对成员的直接访问。如果您需要特殊的访问器,则创建特殊的方法:

void setFoo(const t_foo& foo) {
    assert(foo.isValid());
    this->d_foo = foo;
}

void invalidateFoo() {
    this->d_foo = t_foo::InvalidFoo();
}

b)得到答案:我会经常创建一个内部类(在某些情况下是暂时的):

class C {
    class t_inner {
    public:
    /* ... */
        void setX(int arg) {
            /* enforce some complicated invariants... */
            this->x = arg;
        }
        const int& getX() const {
            /* ... */
            return this->x;
        }
    private:
        int x;
    };
public:
/* ... */
private:
/* ... */
    void m() {
        this->inner().setX(5);
    }
private:
    t_inner d_inner;
};
于 2011-08-25T08:42:22.270 回答
0

明确的答案是否定的。没有语言功能;你可以做一些变化来实现它,但这会使你的代码混乱。

于 2011-08-25T08:38:10.937 回答
0

在 Visual C++ 中,__declspec( property )可以使用具有此功能:

__declspec(property(put=setFunction, get=getFunction)) data-type property-name; 

看这篇文章

于 2011-08-25T09:03:25.397 回答