只允许访问对象的成员,而不是对象本身
Only allow access to an object's members, not the object itself
给出以下 class:
class Foo
{
public:
//...
private:
Bar mBar;
};
是否可以公开 mBar
成员,使其成员可以访问,但不能访问 mBar
对象本身?
原因是用户应该能够访问 mBar
的所有成员,但他们不应该能够将另一个 Bar
实例分配给 mBar
。
Bar
有很多成员,写 getters/setters 并为他们全部转发函数会很麻烦。但是如果 mBar
变成了 public 就可以做到 aFoo.mBar = Bar(/*...*/);
这是唯一不应该被允许的事情。
删除 Bar
的赋值运算符不是一个选项。
我可能会重新考虑您的设计,但这里有一种使用中间 get
方法的可能间接方法:
struct Bar {
int intAttr;
};
class Foo {
Bar mBar;
public:
template <class U>
U& get(U Bar::* p) {
return mBar.*p;
}
};
这样,您可以使用以下方式访问 mBar
的任何 public 成员:
Foo foo;
foo.get(&Bar::intAttr); // get
foo.get(&Bar::intAttr) = 0; // set
如果你只想防止错误而不是马基雅维利,operator->
可能会有所帮助(你可能想要一个包装器而不是直接将它放在 foo 中):
class Foo
{
public:
//...
const Bar* operator ->() const { return &mBar; }
Bar* operator ->() { return &mBar; }
private:
Bar mBar;
};
所以
Foo foo;
foo->bar_member;
foo.foo_member;
// Machiavelli
*foo.operator->() = Bar();
给出以下 class:
class Foo
{
public:
//...
private:
Bar mBar;
};
是否可以公开 mBar
成员,使其成员可以访问,但不能访问 mBar
对象本身?
原因是用户应该能够访问 mBar
的所有成员,但他们不应该能够将另一个 Bar
实例分配给 mBar
。
Bar
有很多成员,写 getters/setters 并为他们全部转发函数会很麻烦。但是如果 mBar
变成了 public 就可以做到 aFoo.mBar = Bar(/*...*/);
这是唯一不应该被允许的事情。
删除 Bar
的赋值运算符不是一个选项。
我可能会重新考虑您的设计,但这里有一种使用中间 get
方法的可能间接方法:
struct Bar {
int intAttr;
};
class Foo {
Bar mBar;
public:
template <class U>
U& get(U Bar::* p) {
return mBar.*p;
}
};
这样,您可以使用以下方式访问 mBar
的任何 public 成员:
Foo foo;
foo.get(&Bar::intAttr); // get
foo.get(&Bar::intAttr) = 0; // set
如果你只想防止错误而不是马基雅维利,operator->
可能会有所帮助(你可能想要一个包装器而不是直接将它放在 foo 中):
class Foo
{
public:
//...
const Bar* operator ->() const { return &mBar; }
Bar* operator ->() { return &mBar; }
private:
Bar mBar;
};
所以
Foo foo;
foo->bar_member;
foo.foo_member;
// Machiavelli
*foo.operator->() = Bar();