最新封装说我有一类Foo
,象这样一个vector_
数据成员:通过返回非const引用成员
class Foo {
public:
const std::vector<int> & vector() const {
return vector_;
}
void vector(const std::vector<int> &vector) {
vector_ = vector;
// Other operations which need to be done after the
// vector_ member has changed
}
private:
// Some large vector
std::vector<int> vector_;
};
我经常遇到这样的
void someOperation(std::vector<int> &v) {
// Operate on v, but almost always let v's size constant
}
int main() {
// Create Foo object
Foo foo;
// Long loop
for (auto k = 0; k < 100; k++) {
auto v = foo.vector();
someOperation(v);
foo.vector(v);
}
}
的情况下,我可以由于vector
访问成员的方法(const
正确)实现,因此不会将foo
的(可能很大)vector_
成员直接传递给someOperation
。虽然someOperation
几乎总是让它的参数大小不变,但我需要首先复制矢量,然后将其传递给someOperation
,然后传递给foo
的setter。很显然,我能避免额外的副本,如果我删除const
-ness的Foo
的类的getter和之后的成员已被someOperation
改变调用一个方法afterChange
- 但是这打破封装:
class Foo {
public:
std::vector<int> & vector() { // Note we now return by non-const reference
return vector_;
}
void afterChange() {
// Other operations which need to be done after the
// vector_ member has changed
}
private:
std::vector<int> vector_;
};
是否有任何其他的选择?或者这是破解封装合法的情况之一?
在我看来,也许'someOperation'应该是对'foo'对象的操作,而不是它应该是'Foo'类中的成员函数。 –
在我看来,如果将此向量传入和传出类对象以进行常规处理,则实际上没有任何封装可以中断。 – Galik
@Galik:我不确定我是否明白你的观点。如果该成员是从类外部修改的(例如,通过返回一个非''contst'引用),我打破封装(也请注意,setter可能会在成员更改后执行其他操作)。我认为@RichardHodges提到的替代方案可以更加明确地改变成员,同时提高效率。 – Marcel