为什么同一类的对象可以访问彼此的私有数据?

发布于 2024-11-27 15:02:35 字数 552 浏览 2 评论 0原文

为什么同一类的对象可以访问彼此的私有数据?

class TrivialClass {
public: 
  TrivialClass(const std::string& data) :
    mData(data) {};

  const std::string& getData(const TrivialClass& rhs) const {
    return rhs.mData;
  };

private:
  std::string mData;
};

int main() {
  TrivialClass a("fish");
  TrivialClass b("heads");

  std::cout << "b via a = " << a.getData(b) << std::endl;
  return 0;
}

这段代码有效。对象 a 完全有可能访问对象 b 的私有数据并返回它。为什么会这样呢?我认为私人数据是私人的。 (我一开始尝试理解 pimpl 习惯用法中的复制构造函数,但后来我发现我什至不理解这个简单的情况。)

Why do objects of the same class have access to each other's private data?

class TrivialClass {
public: 
  TrivialClass(const std::string& data) :
    mData(data) {};

  const std::string& getData(const TrivialClass& rhs) const {
    return rhs.mData;
  };

private:
  std::string mData;
};

int main() {
  TrivialClass a("fish");
  TrivialClass b("heads");

  std::cout << "b via a = " << a.getData(b) << std::endl;
  return 0;
}

This code works. It is perfectly possible for object a to access private data from object b and return it. Why should this be so? I would think that private data is private. (I started out by trying to understand copy constructors in the pimpl idiom, but then I discovered that I didn't even understand this simple situation.)

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

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

发布评论

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

评论(7

愛放△進行李 2024-12-04 15:02:35

因为这就是 C++ 中的工作原理。在 C++ 中,访问控制基于每个类,而不是基于每个对象。

C++ 中的访问控制是作为静态、编译时功能实现的。我认为很明显,在编译时实现任何有意义的每个对象访问控制实际上是不可能的。只有每类控制才能以这种方式实现。

受保护访问规范中存在一些针对每个对象控制的提示,这就是为什么它甚至在标准 (11.5) 中拥有自己的专用章节。但其中描述的每个对象的特征仍然相当初级。同样,C++ 中的访问控制是针对每个类进行的。

Because that's how it works in C++. In C++ access control works on per-class basis, not on per-object basis.

Access control in C++ is implemented as a static, compile-time feature. I think it is rather obvious that it is not really possible to implement any meaningful per-object access control at compile time. Only per-class control can be implemented that way.

Some hints of per-object control are present in protected access specification, which is why it even has its own dedicated chapter in the standard (11.5). But still any per-object features described there are rather rudimentary. Again, access control in C++ is meant to work on per-class basis.

请远离我 2024-12-04 15:02:35

“私人”实际上并不是一种访问控制机制,即“我在 Facebook 上将我的照片设为私人,这样你就看不到它们了”。

在 C++ 中,“private”只是表示这些是类的一部分,您(类的编码人员)可能会在未来版本等中更改它们,并且您不希望使用您的类的其他编码人员依赖它们的存在或功能。

如果您想要真正的访问控制,您应该实施真正的数据安全技术。

"Private" isn't really an access control mechanism in the sense of "I made my pictures on facebook private so you can't see them."

In C++, "private" simply says these are parts of a class that you (the coder of the class) might change in future versions, etc., and you don't want other coders using your class to rely on their existence or functionality.

If you want true access control, you should implement genuine data security techniques.

﹏雨一样淡蓝的深情 2024-12-04 15:02:35

这在某种程度上是一种任意的语言设计决策。例如,在 Ruby 中,private 确实意味着私有,如“仅实例可以访问它自己的私有数据成员”。然而,这有些限制。

正如注释中所指出的,复制构造函数和赋值运算符是直接访问另一个实例的私有数据成员的常见位置。还有一些不太明显的原因。

考虑以下情况。您正在实现一个面向对象的链表。链表有一个用于管理指针的嵌套节点类。您可以实现此节点类,使其管理指针本身(而不是公开指针并由列表管理)。在这种情况下,节点对象会想要在典型的复制构造函数和赋值运算符之外的其他位置修改其他节点对象的指针。

It's somewhat of an arbitrary language design decision. In Ruby, for instance, private really means private, as in "only the instance can access its own private data members". However, this is somewhat restrictive.

As pointed in the comments, copy constructors and assignment operators are common places where you access another instance's private data members directly. There are less obvious reasons why.

Consider the following case. You're implementing an OO linked-list. The linked-list has a nested node class for managing pointers. You might implement this node class such that it manages the pointers itself (rather than having the pointers public and managed by the list). In such a case, you'd have the node objects wanting to modify other node objects' pointers at other places that the typical copy constructor and assignment operator.

瀟灑尐姊 2024-12-04 15:02:35

这是一个很好的问题,我最近也遇到了这个问题。我与同事进行了一些讨论,以下是我们讨论的摘要:
这是设计使然。这并不意味着这种设计对于所有情况都是完全合理的,但是必须考虑为什么选择每类私有。我们能想到的可能原因包括:

首先,每个实例访问控制的成本可能非常高。此主题中的其他人已对此进行了讨论。理论上,这可以通过this指针检查来完成。但是,这不能在编译时完成,只能在运行时完成。因此,您必须在运行时识别每个成员的访问控制,并且当违反时可能只会引发异常。成本很高。

其次,每个类的访问控制都有自己的用例,例如复制构造函数或运算符=。如果访问控制是按实例进行的,那么实现它们将很困难。

另外,访问控制主要是从编程/语言的角度来看,如何模块化/控制对代码/成员的访问,而不是数据。

This is a good question and I have come across this question recently. I had some discussions with my colleagues and here is the summary of our discussion:
This is by design. It doesn't mean this design is totally reasonable for all cases, but there must be some considerations why per class private is chosen. The possible reasons we could think of include:

First of all, the cost of per instance access control could be very high. This has been discussed by others in this thread. In theory, this can be done via this pointer check. However, this cannot be done at compilation time, and can only be done at run time. So you have to identify the access control of each member at run time, and when it's violated possibly only exceptions will be raised. The cost is high.

Secondly, per class access control has its own use case, like copy constructor or operator =. It would be difficult to implement them if access control is per instance.

Plus, the access control is mainly from programming/language perspective, for how to modularise/control the access to the code/member, not the data.

提赋 2024-12-04 15:02:35

诀窍是记住数据是私有,而不是类的实例。类中的任何方法都可以访问该类的任何实例的私有数据;除非您禁止显式访问其他实例的私有数据成员的方法,否则无法将数据保持在实例内私有。

The trick is to remember that the data is private to the class, not the instance of the class. Any method within your class can access the private data of any instance of that class; there's not a way to keep data private to within an instance unless you forbid methods that explicitly access private data members of other instances.

三寸金莲 2024-12-04 15:02:35

除了上面的所有答案之外,请考虑自定义复制构造函数、赋值运算符以及为在其他实例上运行的类编写的所有其他函数。您将需要所有这些数据成员的访问器函数。

In addition to all the answers above, consider custom copy constructors, assignment operators and all the other functions you would write for a class which operate on other instances. You would need accessor functions for all those data members.

傾城如夢未必闌珊 2024-12-04 15:02:35

私有数据将一直保持私有状态,直到有权访问该数据的人将其透露给其他人为止。

这个概念也适用于其他情况,例如:

class cMyClass
{
public:
   // ...
   // omitted for clarity
   // ...

   void Withdraw(int iAmount)
   {
      iTheSecretVault -= iAmount;
   }

private:
   int iTheSecretVault;
};

怎么会有人提取钱? :)

Private data remains private until somebody who has access to it reveal it to other.

This concept applies to other situation too, such as :

class cMyClass
{
public:
   // ...
   // omitted for clarity
   // ...

   void Withdraw(int iAmount)
   {
      iTheSecretVault -= iAmount;
   }

private:
   int iTheSecretVault;
};

How could anyone withdraw the money ? :)

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