7

我听说访问修饰符 Public, Private and Protected只是一些编译器的东西,它们实际上并不存在于编译的二进制代码中。

现在我想知道它有多少是正确的?如果正确,是否意味着运行时二进制代码中不存在封装?所以,如果你修改二进制文件来非法访问某个Private方法,理论上,没有任何东西可以检查你的权限,没有任何OOP机制,也没有操作系统,对吧?

我还标记了 C++ 和 Java 的问题。我知道它们之间的区别,只是想知道它们处理Access Modifiers的方式有何不同。

4

3 回答 3

8

访问修饰符只是 C++ 中的一种编译时机制。然而,在 Java 中,它们也在运行时强制执行,因为 Java 也有一个运行时类型系统,它可以动态(在运行时)创建类。因此,对于在编译时不知道的类型,它也需要在运行时强制访问。

为什么要使用访问修饰符?

访问修饰符的唯一目的是强制设计。

假设你有一个A你实现的类

class A
{
public:
  void DoSomething()
  {
    // use private member mPrivMember to do something
  }
private:
  int mPrivMember;
}

还有一些使用类的代码A

A a_obj;

上面的代码可以调用a_obj.DoSomething(),但是他们没有直接访问 mPrivMember 的权限,所以a.mPrivMember在类之外写的A不会编译。

现在,为什么您希望某些成员可以访问外部代码而某些成员不能访问?好吧,这就是原因:目前,该方法DoSomething()用于mPrivMember实际做事。但一段时间后,您可能决定要重构DoSomething 中的代码,以改进它。你找到了一种不同的方式来做一些不再涉及使用的事情mPrivMember。所以你删除mPrivMemberDoSomething以其他方式重新实现。

现在,如果您的类之外有代码 using mPrivMember,则该代码将不再编译,因为您mPrivMember在重新实现时删除了DoSomething. 为了防止此类代码的存在,您限制对mPrivMember. 这样做的机制是通过访问限定符,例如privateprotected

这使您可以在将来重构代码,而不必担心其他代码可能会使用内部成员。

回顾

public private并且protected是 C++ 中的编译时机制。它们不存在于程序生成的二进制形式中,因此不会强制执行此类保护。任何东西都可以从任何地方访问。

然而,在 Java 中,如果我没记错的话,可以在运行时创建类。这就是为什么它还必须在运行时检查访问以便它可以强制执行它们的原因,因此Private Public并且Protected确实存在于 Java 二进制文件中。

于 2013-03-22T06:32:39.653 回答
2

请注意,这个答案是关于 Java
Both 的。如果您尝试编译试图访问不可访问的对象或方法的代码,您将收到编译时错误:

在运行时,JVM 检查访问:

如果您尝试在运行时访问,您将收到以下异常。使用不正确的访问级别 java.lang.IllegalAccessError:

希望能帮助到你

于 2013-03-22T06:28:33.087 回答
1

编译的 C++ 代码没有私有/受保护/公共的概念。它归结为机器代码,它没有这些概念。如果没有原生支持,你怎么能支持它们呢?更好的是,你怎么能为此提供本地支持。

访问修饰符适用于人类,而不是机器。访问修饰符是设计方面,而不是安全方面。

tl;博士:当 C++ 代码实际运行时,机器并不知道私有/公共/受保护曾经存在过。

于 2013-03-22T06:32:51.607 回答