为什么我可以在复制构造函数中访问私有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级的私人成员,甚至可以访问另一个实例的私人成员。
为了理解答案,我想提醒你几个概念。
- 不pipe你创build了多less个对象,这个类的内存中只有一个函数的副本。 这意味着function只创build一次。 但是,对于类的每个实例,variables是分开的。
-
this
指针在被调用时传递给每个函数。
现在,这是因为this
指针,函数能够find特定实例的variables。 不pipe它是不是公开的私人的。 它可以在该函数内部访问。 现在,如果我们将一个指针传递给同一个类的另一个对象。 使用这第二个指针,我们将能够访问私人成员。
希望这回答你的问题。
复制构造函数是类的成员函数,因此可以访问类的数据成员,甚至是那些声明为“私人”的。