不要放弃你的内部?[C++]

The*_* do 10 c++ return-value

我正在阅读一本名为"C++编码标准"的书作者:Herb Sutter,Andrei Alexandrescu和本书第42章就是一个例子:(章节很短,所以我正在冒昧并粘贴它的一部分)

考虑:

 class Socket {
 public:
   // … constructor that opens handle_, destructor that closes handle_, etc. …
   int GetHandle() const {return handle_;} // avoid this - (1) <-why this is bad code?
                                           // and why there is a comment to avoid such code??
 private:
   int handle_; // perhaps an OS resource handle
 };
Run Code Online (Sandbox Code Playgroud)

数据隐藏是一种功能强大的抽象和模块化设备(参见第11和41项).但是隐藏数据然后给它提供句柄是弄巧成拙的,就像锁住房子并将钥匙留在锁中一样.这是因为:

客户端现在有两种实现功能的方法:它们可以使用类的抽象(Socket)或直接操作类所依赖的实现(套接字的C风格句柄).在后一种情况下,对象不知道它认为拥有的资源发生了重大变化.现在,类无法可靠地丰富或修饰功能(例如,代理,记录,收集统计信息),因为客户端可以绕过装饰的受控实现以及它认为正在添加的任何不变量,这使得接下来的错误处理成为可能(参见条款70) .

该类无法更改其抽象的底层实现,因为客户端依赖于它:如果稍后升级Socket以支持具有不同低级原语集的不同协议,则调用获取底层handle_并错误地操作它的代码将是静默的破碎.

该类不能强制执行其不变量,因为调用代码可以改变类不知道的状态:例如,有人可以关闭Socket对象使用的句柄而不通过Socket成员函数,从而使对象无效.

客户端代码可以存储您的类返回的句柄,并在您的类的代码使它们失效后尝试使用它们.

这是本书的摘要:

不要过多地自愿:避免将句柄返回到由您的班级管理的内部数据,因此客户端不会无法控制地修改您的对象认为它拥有的状态.

基本上我要求的是:

  1. 为什么标记为(1)的行被列为坏代码的示例(我一直认为返回指针或引用是一个坏主意,但按值返回是正常的.这里他们说按值返回也是个坏主意?)

  2. 是否可能存在'&'缺失,它们的真正含义是不通过引用或指针返回内部数据?

谢谢.

Chu*_*uck 32

我认为你所缺少的是一个句柄 - 即使它是由类型系统中的int表示 - 对某事的引用.这不会返回一些信息值 - 它将对象的内部引用返回给系统资源.该类应该自己管理这个句柄,并且句柄应该只通过类接口受外部世界的影响.


R S*_*hko 9

问题不在于低级别的细节(代码是非常好的C++那种方式).

问题是你正在打破你的抽象.如果在将来,您需要将其更改为某种指针,而不是使用int句柄.如果不破坏任何使用您的类的客户端,您将无法进行更改.

  • 此外,通过向调用者返回某种句柄,调用者可以执行一些意外操作,例如关闭底层套接字.`Socket`类不会意识到这已经发生了,然后会尝试访问已经关闭的句柄. (5认同)