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?