返回成员变量的引用是不好的做法吗? [英] Is returning references of member variables bad practice?

查看:91
本文介绍了返回成员变量的引用是不好的做法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据说下面的内容要比成为第一/第二的公共成员更好。我相信这几乎一样糟糕。如果您要提供一种在类之外访问私有变量的方法,那又有什么用呢?函数不应该

  T First(); void(or T)First(const T&)

示例:

  //示例17-3(b):正确的封装,最初使用内联访问器。以后
// //生活中,如果需要的话,这些可能会发展为非平凡的功能;如果没有,那就没有。
//
template< class T,class U>
类Couple {
Couple():delete_(false){}
T& First(){return first_; }
U& Second(){return second_; }
void MarkDeleted(){delete_ = true; }
bool IsDeleted(){返回Deleted_; }

私人:
T first_;
U second_ ;;
bool deleted_;
};


解决方案

返回引用(或指针)的原因有很多对一个类的内部来说是不好的。从最重要的(我认为是)开始:


  1. 封装:您被破坏了泄漏实现细节,这意味着您不能再根据需要更改类的内部。例如,如果您决定不存储 first _ ,而是要进行动态计算,您将如何返回对其的引用?


  2. 不变不再可持续(对于非const引用):任何人可能会随意访问和修改引用的属性,因此您不能监视其更改。这意味着您无法维护此属性属于其中的不变式。从本质上讲,您的课程正在变成blob。


  3. 生命周期问题不断涌现:很容易保留对它们所属的原始对象之后的属性不再存在。这当然是未定义的行为。例如,大多数编译器都会尝试警告将对对象的引用保留在堆栈上,但我知道没有一个编译器能够对函数或方法返回的引用产生此类警告:您是一个人。


因此,通常最好不要放弃对属性的引用或指针。 甚至不是const的!



对于较小的值,通常足以通过副本传递它们(都 in out ),尤其是现在具有移动语义(在途中)。



对于较大的值,它实际上取决于情况,有时代理可以减轻您的麻烦。



最后,请注意,对于某些班级,拥有公共成员并不算太坏。封装的成员有什么意义?当您发现自己编写的只不过是一组属性(没有任何不变性)的类时,则不要将所有的OO都交给我们,而是为每个变量写一个getter / setter对,而应该考虑将它们公开。 p>

The below is said to be better then having first/second as public members. I believe this is nearly as bad. If you're giving a way to access a private variable outside of the class then whats the point? Shouldn't the functions be

T First(); void(or T) First(const T&)

Sample:

// 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_;
};

解决方案

There are several reasons why returning references (or pointers) to the internals of a class are bad. Starting with (what I consider to be) the most important:

  1. Encapsulation is breached: you leak an implementation detail, which means that you can no longer alter your class internals as you wish. If you decided not to store first_ for example, but to compute it on the fly, how would you return a reference to it ? You cannot, thus you're stuck.

  2. Invariant are no longer sustainable (in case of non-const reference): anybody may access and modify the attribute referred to at will, thus you cannot "monitor" its changes. It means that you cannot maintain an invariant of which this attribute is part. Essentially, your class is turning into a blob.

  3. Lifetime issues spring up: it's easy to keep a reference or pointer to the attribute after the original object they belong to ceased to exist. This is of course undefined behavior. Most compilers will attempt to warn about keeping references to objects on the stack, for example, but I know of no compiler that managed to produce such warnings for references returned by functions or methods: you're on your own.

As such, it is usually better not to give away references or pointers to attributes. Not even const ones!

For small values, it is generally sufficient to pass them by copy (both in and out), especially now with move semantics (on the way in).

For larger values, it really depends on the situation, sometimes a Proxy might alleviate your troubles.

Finally, note that for some classes, having public members is not so bad. What would be the point of encapsulating the members of a pair ? When you find yourself writing a class that is no more than a collection of attributes (no invariant whatsoever), then instead of getting all OO on us and writing a getter/setter pair for each of them, consider making them public instead.

这篇关于返回成员变量的引用是不好的做法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆