最新封裝說我有一類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