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

发布于 2024-10-01 04:11:24 字数 363 浏览 14 评论 0原文

我了解到我永远无法访问私有变量,只能使用类中的 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;

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?

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

晚雾 2024-10-08 04:11:24

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

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

原因:

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

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

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

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.

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.

来日方长 2024-10-08 04:11:24

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

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

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

它不仅仅是复制构造函数 - 很多操作都可能涉及类的两个或多个实例:如果您要进行比较、加/乘/除、复制构造、克隆、赋值等,那么通常情况下,您要么只是必须能够访问另一个对象中的私有和/或受保护的数据,要么希望它允许更简单、更快或通常更好的函数实现。

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

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

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:

  • derived classes are able to interact with it (through optionally-pure virtual functions and/or protected access), and
  • distinct X objects cooperate to provide intended behaviours while honouring the post-conditions and invariants from your design.

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_ptrs 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 expose begin() and end() iterators - with direct access to size() you could reserve capacity for faster copying; worse still if they only expose at() and insert() and otherwise throw....
  • copy references back to parent/coordination/management objects that might be unknown or write-only for the client code
拥有 2024-10-08 04:11:24

您可以从类内部访问该类的私有成员,甚至可以访问另一个实例的私有成员。

You can access private members of a class from within the class, even those of another instance.

童话 2024-10-08 04:11:24

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

  1. 无论您创建多少个对象,该类的内存中都只有一个函数的一份副本。这意味着函数只创建一次。然而,该类的每个实例的变量都是独立的。
  2. this 指针在调用时会传递给每个函数。

现在,由于 this 指针,函数能够定位该特定实例的变量。无论是私人的还是公共的。可以在该函数内部访问它。现在,如果我们将指针传递给同一类的另一个对象。使用第二个指针,我们将能够访问私有成员。

希望这能回答您的问题。

To understand the answer, I would like to remind you few concepts.

  1. 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.
  2. this pointer is passed to every function when called.

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.

Hope this answers your question.

如此安好 2024-10-08 04:11:24

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

Copy constructor is class' member function and as such has access to class' data members, even those declared as 'private'.

初见你 2024-10-08 04:11:24

为什么制作该编译器的人允许这种行为,
我们可以在复制构造函数或类中的任何方法中看到对象的隐藏成员(其类型与访问隐藏成员的类相同)

答案:因为当你在课堂上时,这意味着你是课堂的构建者或设计者,也意味着你知道所有内容该类中的数据成员和方法,这就是他允许这种行为的原因,因为您构建了这个类,您知道有关它的所有事情,不像该类的用户,他们不必像您一样了解有关该类的所有事情。

隐藏数据成员或方法的想法可以帮助此类的用户,并且不会将他们与不重要的事情混淆。

就是这样。

why the man who made that compiler allow this behavior,
that we can see hidden members of an object (that its type is the same of the class where you access the hidden members) in copy constructor or in any method in the class.

The answer: because you when you are in the class that's mean you are the builder or the designer of the class also mean that you know all data members and methods in that class that's why he allow this behavior because you build this class you know every thing about it unlike the users of the class they haven't to know every thing about the class like you.

the idea of hiding data members or method that help the users of this class and not confused them with non important things.

That's it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文