C++ 通过向成员返回非常量引用来破坏封装
假设我有一个classC++ 通过向成员返回非常量引用来破坏封装,c++,c++11,C++,C++11,假设我有一个classFoo和一个vector数据成员,如下所示: class Foo { public: const std::vector<int> & vector() const { return vector_; } void vector(const std::vector<int> &vector) { vector_ = vector; // Other operati
Foo
和一个vector
数据成员,如下所示:
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_;
};
还有其他选择吗?或者这是破坏封装合法的情况之一?在您的情况下,您可以只更改
someOperation()
以在一个范围内工作,而不是向量本身。然后,您的Foo
类将需要begin()
和end()
函数,返回适当的迭代器。在您的情况下,您可以通过将向量移出类,然后再回到类中来获得一些效率:
class Foo {
public:
std::vector<int>&& take_vector() {
return std::move(vector_);
}
void vector(std::vector<int> vector) {
vector_ = std::move(vector);
// Other operations which need to be done after the
// vector_ member has changed
}
private:
// Some large vector
std::vector<int> vector_;
};
class-Foo{
公众:
std::vector&&take_vector(){
返回std::move(向量_);
}
无效向量(标准::向量向量){
向量=标准::移动(向量);
//完成后需要进行的其他操作
//向量成员已更改
}
私人:
//一些大向量
std::矢量;
};
然后
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++) {
// this is a very cheap move
auto v = foo.take_vector();
someOperation(v);
// so is this
foo.vector(std::move(v));
}
}
void someOperation(std::vector&v){
//在v上操作,但几乎总是让v的大小保持不变
}
int main(){
//创建Foo对象
富富,;
//长环
用于(自动k=0;k<100;k++){
//这是一个非常便宜的举动
自动v=foo.take_vector();
手术(v);
//这也是
foo.vector(std::move(v));
}
}
或者,您可以将向量上的操作构造为访问者:
class Foo {
public:
template<class F>
void apply_op(F&& op) {
op(vector_);
// Other operations which need to be done after the
// vector_ member has changed
}
private:
// Some large vector
std::vector<int> vector_;
};
class-Foo{
公众:
模板
无效应用操作(F&op){
op(向量!;
//完成后需要进行的其他操作
//向量成员已更改
}
私人:
//一些大向量
std::矢量;
};
这样调用:
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++)
{
foo.apply_op(&someOperation);
}
}
void someOperation(std::vector&v){
//在v上操作,但几乎总是让v的大小保持不变
}
int main(){
//创建Foo对象
富富,;
//长环
用于(自动k=0;k<100;k++)
{
foo.apply_op(&someOperation);
}
}
在我看来,someOperation
应该是foo
对象上的操作,也就是说,它应该是Foo
类中的一个成员函数。在我看来,如果这个向量被传入或传出类对象进行常规处理,那么你就没有任何封装可以打破。@Galik:我不确定我是否明白你的意思。如果该成员是从类外部修改的(例如,通过返回非常量
引用),我将中断封装(还请注意,setter可能在该成员更改后执行其他操作)。我认为@RichardHodges提到的替代方法可以使更改成员更加明确,同时提高效率。下面是Visual Studio的正则表达式,它可以帮助找到返回非常量引用的方法:(?]*>\s*)*&\s+\w+(?::\w+*\s*\(
-可能不完美,有人可以提出改进建议!相关:
class Foo {
public:
template<class F>
void apply_op(F&& op) {
op(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++)
{
foo.apply_op(&someOperation);
}
}