为什么我可以在复制构造函数中访问私有变量?

新手上路,请多包涵

我了解到我永远无法访问私有变量,只能使用类中的 get 函数。但是为什么我可以在复制构造函数中访问它呢?

例子:

 Field::Field(const Field& f)
{
  pFirst = new T[f.capacity()];

  pLast = pFirst + (f.pLast - f.pFirst);
  pEnd  = pFirst + (f.pEnd - f.pFirst);
  std::copy(f.pFirst, f.pLast, pFirst);
}

我的声明:

 private:
  T *pFirst,*pLast,*pEnd;

原文由 demonking 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 617
2 个回答

恕我直言,现有的答案在解释这个“为什么”方面做得很差——过于关注重申什么行为是有效的。 “访问修饰符在类级别上起作用,而不是在对象级别上。” - 是的,但是为什么?

这里的总体概念是,设计、编写和维护一个类的程序员应该理解所需的 OO 封装并有权协调其实现。因此,如果您正在编写 class X ,那么您所编码的不仅仅是单个 X x 对象可以由可以访问它的代码使用,还包括如何:

  • 派生类能够与其交互(通过可选的纯虚函数和/或受保护的访问),并且
  • distinct X 对象 合作 提供预期的行为,同时尊重设计中的后置条件和不变量。

也不仅仅是复制构造函数 - 大量操作可能涉及您的类的两个或多个实例:如果您正在比较、添加/乘法/除法、复制构造、克隆、分配等,那么您通常会遇到这种情况要么只是必须访问另一个对象中的私有和/或受保护数据,要么希望它允许更简单、更快或通常更好的功能实现。

具体来说,这些操作可能希望利用特权访问来执行以下操作:

  • (复制构造函数)在初始化列表中使用“rhs”(右侧)对象的私有成员,以便成员变量本身是复制构造的,而不是默认构造的(如果甚至合法)然后也分配(再次,如果合法)
  • 共享资源 - 文件句柄、共享内存段、 shared_ptr 引用数据等。
  • 取得事物的所有权,例如 auto_ptr<> “移动”所有权到正在建设的对象
  • 复制私有“缓存”、校准或状态成员,以便在最佳可用状态下构建新对象,而无需从头开始重新生成它们
  • 复制/访问保存在被复制对象中的诊断/跟踪信息,这些信息不能通过公共 API 以其他方式访问,但可能会被一些以后的异常对象或日志记录使用(例如,关于“原始”非复制构造实例时的时间/情况已建成)
  • 对某些数据执行更有效的复制:例如对象可能具有 unordered_map 成员,但仅公开公开 begin()end() 迭代器 - 可直接访问 size() 你可以 reserve 更快复制的能力;更糟糕的是,如果他们只公开 at()insert() 否则 throw ….
  • 将引用复制回可能未知或客户端代码只写的父/协调/管理对象

原文由 Tony Delroy 发布,翻译遵循 CC BY-SA 3.0 许可协议

访问修饰符作用于 类级别,而不是 对象级别

也就是说,同一类的两个对象可以访问彼此的私有数据。

为什么:

主要是因为效率。每次访问 other.x 时检查 this == other 是否是不可忽略的运行时开销,如果访问修饰符在对象级别工作,则必须这样做。

如果您从作用域的角度来考虑它,这在语义上也是合乎逻辑的:“在修改私有变量时,我需要记住多少部分代码?” – 您需要牢记整个类的代码,这与运行时中存在哪些对象是正交的。

在编写复制构造函数和赋值运算符时非常方便。

原文由 aioobe 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题