OOP访问修饰符:编译时或运行时

OOP Access Modifiers: Compile-time or Run-time

本文关键字:编译 运行时 访问 OOP      更新时间:2023-10-16

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

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

我还标记了c++和Java的问题。我知道它们之间的区别,只是好奇它们如何处理访问修饰符

访问修饰符仅仅是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类之外的a.mPrivMember将无法编译。

现在,为什么你希望一些成员可以被外部代码访问而另一些则不能呢?好吧,原因如下:目前,DoSomething()方法使用mPrivMember来实际执行操作。但过了一段时间后,您可能决定要重构DoSomething中的代码,以改进它。你发现了一种不同的方法来做一些不涉及使用mPrivMember了。所以你删除mPrivMember并以其他方式重新实现DoSomething

现在,如果在你的类之外有代码使用mPrivMember,那么这些代码将不再编译,因为你在重新实现DoSomething时删除了mPrivMember。为了防止此类代码的存在,可以限制对mPrivMember的访问。实现这一点的机制是通过访问限定符,如privateprotected

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

回顾

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

在Java中,类可以在运行时创建,如果我没有弄错的话。这就是为什么它也必须在运行时检查访问,以便它可以强制执行它们,因此Private PublicProtected确实存在于Java二进制文件中。

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

和在运行时,JVM检查访问:

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

希望有所帮助

编译后的c++代码没有private/protected/public的概念。它可以归结为机器代码,而机器代码没有这些概念。如果没有本地支持,你怎么能支持它们呢?更妙的是,你怎么可能为它提供本地支持呢?

访问修饰符是为人类设计的,不是为机器设计的。访问修饰符是一个设计方面,而不是一个安全方面。

tl;dr:到c++代码实际运行时,机器还不知道private/public/protected存在

相关文章: