C++ 为什么我可以在复制构造函数中访问私有变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4117002/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can I access private variables in the copy constructor?
提问by demonking
I have learned that I can never access a private variable, only with a get-function in the class. But then why can I access it in the copy constructor?
我了解到我永远无法访问私有变量,只能使用类中的 get 函数。但是为什么我可以在复制构造函数中访问它呢?
Example:
例子:
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);
}
My declaration:
我的声明:
private:
T *pFirst,*pLast,*pEnd;
采纳答案by Tony Delroy
IMHO, existing answers do a poor job explaining the "Why" of this - focusing too much on reiterating what behaviour's valid. "access modifiers work on class level, and not on object level." - yes, but why?
恕我直言,现有的答案在解释“为什么”这一点上做得很差 - 过于关注重申什么行为是有效的。“访问修饰符在类级别工作,而不是在对象级别。” - 是的,但是为什么?
The overarching concept here is that it's the programmer(s) designing, writing and maintaining a class who is(are) expected to understand the OO encapsulation desired and empowered to coordinate its implementation. So, if you're writing class X
, you're encoding not just how an individual X x
object can be used by code with access to it, but also how:
这里的总体概念是,设计、编写和维护类的程序员应该了解所需的 OO 封装并有权协调其实现。因此,如果您正在编写class X
,您不仅要编码X x
具有访问权限的代码如何使用单个对象,还要编码如何:
- derived classes are able to interact with it (through optionally-pure virtual functions and/or protected access), and
- distinct
X
objects cooperateto provide intended behaviours while honouring the post-conditions and invariants from your design.
- 派生类能够与其交互(通过可选的纯虚函数和/或受保护的访问),以及
- 不同的
X
对象合作提供预期的行为,同时尊重设计中的后置条件和不变量。
It's not just the copy constructor either - a great many operations can involve two or more instances of your class: if you're comparing, adding/multiplying/dividing, copy-constructing, cloning, assigning etc. then it's often the case that you either simply must have access to private and/or protected data in the other object, or want it to allow a simpler, faster or generally better function implementation.
这不仅仅是复制构造函数 - 很多操作可能涉及您的类的两个或多个实例:如果您正在比较,添加/乘法/除法,复制构造,克隆,分配等,那么通常情况下您要么只是必须能够访问另一个对象中的私有和/或受保护的数据,要么希望它允许更简单、更快或通常更好的功能实现。
Specifically, these operations may want to take advantage of priviledged access to do things like:
具体来说,这些操作可能希望利用特权访问来执行以下操作:
- (copy constructors) use a private member of the "rhs" (right hand side) object in an initialiser list, so that a member variable is itself copy-constructed instead of default-constructed (if even legal) then assigned too (again, if legal)
- share resources - file handles, shared memory segments,
shared_ptr
s to reference data etc. - take ownership of things, e.g.
auto_ptr<>
"moves" ownership to the object under construction - copy private "cache", calibration, or state members needed to construct the new object in an optimally usable state without having to regenerate them from scratch
- copy/access diagnostic/trace information kept in the object being copied that's not otherwise accessible through public APIs but might be used by some later exception object or logging (e.g. something about the time/circumstances when the "original" non-copy-constructed instance was constructed)
- perform a more efficient copy of some data: e.g. objects may have e.g. an
unordered_map
member but publicly only exposebegin()
andend()
iterators - with direct access tosize()
you couldreserve
capacity for faster copying; worse still if they only exposeat()
andinsert()
and otherwisethrow
.... - copy references back to parent/coordination/management objects that might be unknown or write-only for the client code
- (复制构造函数)在初始化列表中使用“rhs”(右侧)对象的私有成员,以便成员变量本身是复制构造的,而不是默认构造的(如果甚至合法),然后也分配(再次,如果合法)
- 共享资源 - 文件句柄、共享内存段、
shared_ptr
引用数据的 s 等。 - 取得事物的所有权,例如
auto_ptr<>
将所有权“转移”给正在建造的对象 - 复制私有“缓存”、校准或状态成员以构建处于最佳可用状态的新对象,而无需从头开始重新生成它们
- 复制/访问诊断/跟踪信息保存在被复制的对象中,这些信息不能通过公共 API 以其他方式访问,但可能会被某些稍后的异常对象或日志记录使用(例如,有关“原始”非复制构造实例的时间/环境的信息构造)
- 对某些数据执行更有效的复制:例如,对象可能有一个
unordered_map
成员,但仅公开公开begin()
和end()
迭代器 - 直接访问size()
您可以reserve
加快复制速度;更糟的是,如果他们只会暴露at()
和insert()
否则throw
.... - 将引用复制回对客户端代码可能未知或只写的父/协调/管理对象
回答by aioobe
The access modifiers work on class level, and not on object level.
访问修饰符在类级别起作用,而不是在对象级别起作用。
That is, two objects of the same class can access each others private data.
也就是说,同一类的两个对象可以访问彼此的私有数据。
Why:
为什么:
Primarily due to efficiency. It would be a non-negligible runtime overhead to check if this == other
each time you access other.x
which you would have to if the access modifiers worked on object level.
主要是因为效率。如果访问修饰符在对象级别工作,则检查this == other
每次访问other.x
时是否必须进行检查,这将是一个不可忽略的运行时开销。
It's also kind of semantically logical if you think of it in terms of scoping: "How big part of the code do I need to keep in mind when modifying a private variable?" – You need to keep the code of the whole class in mind, and this is orthogonal to which objects exist in runtime.
如果您从作用域的角度考虑,这在语义上也是合乎逻辑的:“在修改私有变量时,我需要记住代码的多大部分?” – 你需要记住整个类的代码,这与运行时存在的对象是正交的。
And it's incredibly convenient when writing copy constructors and assignment operators.
而且在编写复制构造函数和赋值运算符时非常方便。
回答by Alexander Rafferty
You can access private members of a class from within the class, even those of another instance.
您可以从类内部访问类的私有成员,甚至可以访问另一个实例的私有成员。
回答by Ali Zaib
To understand the answer, I would like to remind you few concepts.
为了理解答案,我想提醒你几个概念。
- No matter how many objects you create, there is only one copy of one function in memory for that class. It means functions are created only once. However variables are separate for each instance of the class.
this
pointer is passed to every function when called.
- 无论您创建多少个对象,该类的内存中只有一个函数的副本。这意味着函数只创建一次。但是,对于类的每个实例,变量是分开的。
this
调用时将指针传递给每个函数。
Now it's because of the this
pointer, function is able to locate variables of that particular instance. no matter if it is private of public. it can be accessed inside that function. Now if we pass a pointer to another object of the same class. using this second pointer we will be able to access private members.
现在正是因为this
有了指针,函数才能够定位该特定实例的变量。无论是私人的还是公共的。它可以在该函数内访问。现在,如果我们传递一个指向同一类的另一个对象的指针。使用第二个指针,我们将能够访问私有成员。
Hope this answers your question.
希望这能回答你的问题。
回答by Bojan Komazec
Copy constructor is class' member function and as such has access to class' data members, even those declared as 'private'.
复制构造函数是类的成员函数,因此可以访问类的数据成员,甚至那些声明为“私有”的成员。