我听说Access Modifiers Public, Private and Protected只是一些Compiler Stuff,它们实际上并不存在于已编译的二进制代码中

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

我还标记了C ++和Java的问题。 我知道它们之间的区别,只是好奇地看到它们处理Access Modifiers有多么不同。

===============>>#1 票数:7 已采纳

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

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

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

假设您有一个实施的A

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

还有一些使用AA代码:

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二进制文件中。

===============>>#2 票数:2

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

在运行时,JVM检查访问:

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

希望能帮助到你

===============>>#3 票数:1

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

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

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

  ask by Mahdi translate from so

未解决问题?本站智能推荐:

1回复

编译器是否优化这部分代码(常量获取器)?

我有以下类定义: 具有const getter( foo->isActive() )的类的工作速度是否比foo->m_active (如果它将是公共的)更快? 我试图查看反汇编的代码,但没有发现任何有趣的东西。 在哪里可以阅读有关const getter和set
4回复

生产编译器如何在流控制上实现析构函数处理

长话短说 - 我正在编写一个编译器,并且达到了OOP功能,我面临着涉及处理析构函数的两难问题。 基本上我有两个选择: 1 - 将所有析构函数放在程序中该点需要调用的对象上。 这个选项听起来像是性能友好且简单但会使代码膨胀,因为根据控制流程,某些析构函数可以多次复制。 2 -
9回复

是否有更现代的OO版“让我们构建一个编译器”? [关闭]

是否有更现代的,可能是面向对象的,相当于Jack Crenshaw的“ Let's Build a Compiler ”系列? 不久前,我偶然发现了“ 让我们构建一个编译器 ”,并且无法抗拒编写一些代码。 我在C#中编写了一个递归下降的C编译器,输出.NET CIL。 “写一次,到处泄
9回复

Java,C ++,Python和ObjC的在线编译器/运行时? [关闭]

有没有人知道我可以在网上访问的良好的在线编译器/运行时(对于C ++,Java,Python,ObjC等)? 我正在寻找的是允许我在Web表单中键入程序并运行程序并在线查看结果的内容。 (我们现在暂不说明原因。我现在只想说我并不总是能够访问编译器/运行时,而且启动IDE对于测试一些代
9回复

面向对象编程中的访问修饰符

我不理解OOP中的Access Modifiers。 为什么我们在Java实例变量私有中使用,然后使用公共getter和setter方法来访问它们? 我的意思是这背后的推理/逻辑是什么? 您仍然可以访问实例变量但是为什么在可以公开变量时使用setter和getter方法? 请原谅
1回复

运行时动态绑定和类继承之间的区别

我试图澄清动态语言(Python,ruby)和静态类型语言(java,C ++)中运行时动态绑定和类继承的概念。 我不确定我是对的。 在Python和Ruby等动态语言中,运行时动态绑定实现为duck typing。 当解释器检查对象的类型时,它会检查对象是否具有特定的方法(或行为),
3回复

私有访问权和公共访问修饰符在性能上有所不同吗?

我认为我们必须在成员变量上使用正确的修饰符以实现模块化,但对类成员的访问修饰符对应用程序性能的影响感到好奇。 如果我的程序很小,那么如果我使用所有成员变量public怎么办?
2回复

为JVM编译C ++

编译C ++时,您当然会为要编译的目标平台使用编译器。 是否有针对JVM的C ++编译器(因此,不是使用Java“本机”接口,而是将C ++代码编译为Java字节码)?
13回复

如何驱动C#,C ++或Java编译器在编译时计算1 + 2 + 3 + ... + 1000?

在最近的一次采访中,我被问到一个非常奇怪的问题。 面试官问我如何使用编译器功能计算1 + 2 + 3 + ... + 1000。 这意味着我不允许编写程序并执行它,但我应该编写一个程序,可以驱动编译器在编译时计算这个总和,并在编译完成时打印结果。 作为提示,他告诉我,我可能会使用编译器的泛
3回复

使用通配符将Java泛型编译为C ++模板

我正在尝试构建Java到C ++的转换器(即Java代码进入,语义上“等效”(或多或少)C ++代码出来)。 不考虑垃圾收集,语言非常熟悉,因此整个过程已经很好用了。 然而,一个问题是C ++中不存在的泛型。 当然,最简单的方法是执行java编译器所做的擦除。 但是,生成的C ++代