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

我已经了解到,我永远不能访问一个私有variables,只能在类中使用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; 

恕我直言,现有的答案做了一个糟糕的工作解释这个“为什么” – 太过分重视重复什么样的行为是有效的。 “访问修饰符在类级别而不是在对象级别上工作。” – 是的,但是为什么?

这里的总体概念是devise,编写和维护一个class级的程序员,他们期望理解OO封装的期望和授权来协调其实现。 因此,如果您正在编写class X ,那么您不仅要编码访问它的代码如何使用单个X x对象,还要编码如何:

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

这不仅仅是拷贝构造函数 – 许多操作可能涉及两个或更多类的实例:如果您正在比较,添加/相乘/划分,复制构build,克隆,分配等,那么通常情况下,您要么只是必须有权访问另一个对象中的私有和/或受保护的数据,或者希望它允许更简单,更快或者通常更好的function实现。

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

  • (复制构造函数)在初始化列表中使用“rhs”(右侧)对象的私有成员,以便成员variables本身是复制构造而不是默认构造的(如果合法的话)如果合法)
  • 共享资源 – 文件句柄,共享内存段, shared_ptr s引用数据等
  • 取得东西的所有权,例如auto_ptr<> “将所有权”移动到正在build造的对象上
  • 复制私有“caching”,校准或状态成员需要构build新的对象在一个最佳的可用状态,而不必从头再生
  • 复制/访问保存在被复制对象中的诊断/跟踪信息,这些信息不能以其他方式通过公共API访问,但可能会被某些后来的exception对象或日志所使用(例如,关于“原始”非复制构造实例的时间/情况被构造)
  • 执行一些数据的更高效的副本:例如,对象可能有例如一个unordered_map成员,但公开只公开begin()end()迭代器 – 直接访问size()可以reserve容量以加快复制; 更糟糕的是,如果他们只暴露at()insert() ,否则throw ….
  • 将引用复制回客户端代码可能未知或只写的父/协调/pipe理对象

访问修饰符在类级别上工作,而不是在对象级别上

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

为什么:

主要是由于效率。 每次访问other.x时,检查this == other是否是一个不可忽略的运行时间开销,如果访问修饰符在对象级别上工作,您将不得不这样做。

如果按照范围界定来考虑它,那么它在语义上也是合乎逻辑的:“修改私有variables时需要记住多大的代码? – 您需要记住整个class级的代码,这与运行时存在哪些对象是正交的。

编写拷贝构造函数和赋值操作符时非常方便。

您可以从课程内部访问某个class级的私人成员,甚至可以访问另一个实例的私人成员。

为了理解答案,我想提醒你几个概念。

  1. 不pipe你创build了多less个对象,这个类的内存中只有一个函数的副本。 这意味着function只创build一次。 但是,对于类的每个实例,variables是分开的。
  2. this指针在被调用时传递给每个函数。

现在,这是因为this指针,函数能够find特定实例的variables。 不pipe它是不是公开的私人的。 它可以在该函数内部访问。 现在,如果我们将一个指针传递给同一个类的另一个对象。 使用这第二个指针,我们将能够访问私人成员。

希望这回答你的问题。

复制构造函数是类的成员函数,因此可以访问类的数据成员,甚至是那些声明为“私人”的。