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

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

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 codes 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.)

37746 次浏览

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;
};

怎么会有人把钱取出来

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

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 受保护的访问 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.

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

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

考虑下面的情况。您正在实现一个 OO 链表。该链表有一个用于管理指针的嵌套节点类。您可以实现这个节点类,以便它自己管理指针(而不是让指针公开并由列表管理)。在这种情况下,节点对象希望修改其他节点对象在其他地方的指针,而这些地方是典型的复制建构子和赋值操作符。

诀窍是要记住数据是 private同学们,而不是类的 instance。类中的任何方法都可以访问该类的任何实例的私有数据; 除非禁止显式访问其他实例的私有数据成员的方法,否则没有办法将数据保持为实例内的私有数据。

“隐私”并不是 访问控制机制的真正意义上的“我把我在 facebook 上的照片设置为隐私,所以你看不到它们。”

在 C + + 中,“ private”只是简单地说这些是类的一部分,你(这个类的编码者)可能在未来的版本中改变,等等,你不希望其他使用你的类的编码者依赖于他们的存在或功能。

如果希望实现真正的访问控制,则应实现真正的数据安全技术。

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

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

其次,每个类的访问控制都有自己的用例,比如复制建构子或操作符 = 。如果访问控制是针对每个实例的,那么将很难实现它们。

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

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.