Say I have a class Foo
with a vector_
data member like so:
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_;
};
I often face situations like these
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);
}
}
where I can't pass foo
's (possibly large) vector_
member directly to someOperation
due to the (const
-correct) implementation of the vector
method to access the member. Although someOperation
almost always lets its argument's size unchanged, I need to copy the vector first, then pass it to someOperation
and then to foo
's setter. Clearly, I can avoid this extra copy if I remove the const
-ness of the Foo
's class getter and call an afterChange
method after the member has been changed by someOperation
- but this breaks encapsulation:
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_;
};
Are there any other alternatives? Or is this one of the situations where breaking encapsulation is legitimate?
Aucun commentaire:
Enregistrer un commentaire