49 c++ reference member-variables
以下据说比公共成员有第一个/第二个更好.我相信这几乎一样糟糕.如果您正在提供一种方法来访问课外的私有变量,那么重点是什么?功能不应该是
T First(); void(or T) First(const T&)
Run Code Online (Sandbox Code Playgroud)
样品:
// Example 17-3(b): Proper encapsulation, initially with inline accessors. Later
// in life, these might grow into nontrivial functions if needed; if not, then not.
//
template<class T, class U>
class Couple {
Couple() : deleted_(false) { }
T& First() { return first_; }
U& Second() { return second_; }
void MarkDeleted() { deleted_ = true; }
bool IsDeleted() { return deleted_; }
private:
T first_;
U second_;
bool deleted_;
};
Run Code Online (Sandbox Code Playgroud)
Mat*_* M. 55
将引用(或指针)返回到类的内部是不好的有几个原因.从(我认为是)最重要的开始:
封装被破坏:泄漏实现细节,这意味着您不能再按照自己的意愿改变类内部.如果您决定不以存储first_
为例,而是动态计算它,您将如何返回对它的引用?你不能,因此你被卡住了.
不变量不再是可持续的(在非const引用的情况下):任何人都可以随意访问和修改引用的属性,因此您无法"监视"其更改.这意味着您无法维护此属性所属的不变量.从本质上讲,你的班级正在变成一个blob.
生命周期问题出现了:在属性所在的原始对象不再存在之后,很容易保留属性的引用或指针.这当然是未定义的行为.例如,大多数编译器会尝试警告保持对堆栈上对象的引用,但我知道没有编译器能够为函数或方法返回的引用设置这样的警告:你是独立的.
因此,通常最好不要放弃引用或指向属性的指针.甚至不是常数!
对于较小的值,通常足以通过复制(两者in
和两者out
)传递它们,特别是现在使用移动语义(在路上).
对于较大的值,它实际上取决于具体情况,有时代理可能会减轻您的麻烦.
最后,请注意,对于某些课程,拥有公共成员并不是那么糟糕.封装成员的意义是pair
什么?当你发现自己编写一个只是属性集合(没有任何不变量)的类时,那么不要让我们为所有OO编写所有OO并为它们编写getter/setter对,而是考虑将它们公之于众.
iam*_*ind 26
如果template
类型T
和U
大结构然后按价值返回是昂贵的.但是你是正确的,通过引用返回相当于提供对private
变量的访问.要解决这两个问题,请将它们const
作为参考:
const T& First() const { return first_; }
const U& Second() const { return second_; }
Run Code Online (Sandbox Code Playgroud)
PS此外,当没有setter方法时,在构造函数中保持变量未初始化是一种不好的做法.它似乎在原始代码中,First()
并且Second()
是包装器,first_
并且second_
用于读/写两者.
答案取决于人们想要做什么.返回引用是促进数据结构变异的便利方式.一个很好的例子是stl地图.它返回对元素的引用,即
std::map<int,std::string> a;
a[1] = 1;
Run Code Online (Sandbox Code Playgroud)
什么都阻止你做
auto & aref = a[1];
Run Code Online (Sandbox Code Playgroud)
这一定是一种不好的做法吗?我不这么认为.我会说,如果没有它,你可以这样做.如果它让生活更方便和有效地使用它并且意识到你在做什么.
归档时间: |
|
查看次数: |
24294 次 |
最近记录: |