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

时间:2013-03-22 06:22:55

标签: java c++ oop compiler-construction

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

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

我还标记了C ++和Java的问题。我知道它们之间的区别,只是想知道它们处理访问修饰符有多么不同。

3 个答案:

答案 0 :(得分:7)

访问修饰符只是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。因此,您删除mPrivMember并以其他方式重新实现DoSomething

现在,如果您的班级之外的代码使用mPrivMember,则该代码将不再编译,因为您在重新实现mPrivMember时已删除了DoSomething。为防止此类代码存在,您可以限制对mPrivMember的访问权限。执行此操作的机制是通过访问限定符,例如privateprotected

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

小结

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

然而,在Java中,如果我没有弄错的话,可以在运行时创建类。这也是为什么它也必须在运行时检查访问权限以便它可以强制执行它们的原因,因此{2}中存在Private PublicProtected

答案 1 :(得分:2)

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

在运行时,JVM会检查访问权限:

如果您尝试在运行时访问,则会出现以下异常。访问级别不正确java.lang.IllegalAccessError:

希望有所帮助

答案 2 :(得分:1)

编译的C ++代码没有private / protected / public的概念。它归结为机器代码,它没有那些概念。没有原生支持,你怎么能支持他们?更好的是,你怎么能为此做出原生支持。

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

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