OOP访问修饰符:编译时或运行时
OOP Access Modifiers: Compile-time or Run-time
我听说访问修饰符 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
的访问。实现这一点的机制是通过访问限定符,如private
和protected
。
这允许您在将来重构代码,而不必担心其他代码可能使用内部成员。
回顾
public
private
和protected
是c++中的编译时机制。它们不存在于生成的二进制形式的程序中,因此不强制执行此类保护。任何东西都可以从任何地方访问。
在Java中,类可以在运行时创建,如果我没有弄错的话。这就是为什么它也必须在运行时检查访问,以便它可以强制执行它们,因此Private
Public
和Protected
确实存在于Java二进制文件中。
请注意,这个答案是关于Java的
两者都有。如果您试图编译试图访问不可访问的对象或方法的代码,您将得到编译时错误:
和在运行时,JVM检查访问:
如果您试图在运行时访问,您将得到以下异常。访问级别不正确java.lang.IllegalAccessError:
希望有所帮助
编译后的c++代码没有private/protected/public的概念。它可以归结为机器代码,而机器代码没有这些概念。如果没有本地支持,你怎么能支持它们呢?更妙的是,你怎么可能为它提供本地支持呢?
访问修饰符是为人类设计的,不是为机器设计的。访问修饰符是一个设计方面,而不是一个安全方面。
tl;dr:到c++代码实际运行时,机器还不知道private/public/protected存在
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 在运行时解析函数,而不是在编译C++解析函数
- 在编译时,C++项目抛出错误 C2228,这是预期的,因为控件在运行时未达到该点
- 在编译时为运行时设置环境变量
- 运行时检查失败 #0 用于运行时重新编译
- std::tuple 可以根据其值在编译时/运行时排序吗?
- C++项目编译强制使用 /clr 选项,尽管在没有公共语言运行时支持的情况下执行它
- 在编译时而不是运行时创建一个由两个字节组成的值
- scanf() 的宽度说明符 - 要使用的字符长度在编译时不固定,仅在运行时确定.如何使其可变?
- 选择特定版本的 Visual Studio 命令行工具包,并根据特定版本的C++运行时环境编译文件
- C ++中的方法覆盖:是编译时还是运行时多态性?
- C++:此代码可以编译,但引发运行时检查失败 #2 - 围绕变量周围的堆栈'num'已损坏。发生
- C++代码在 for 循环的条件下给出运行时错误,而如果它被具有相同意义的代码替换,则编译正确
- C++编译时和运行时可用的名称属性
- C++代码编译,但在 Zorin OS 上运行时显示错误
- 静态类型是在编译时还是运行时强制实施的?
- 在函数中创建的数组,编译时还是运行时?
- 我正在尝试使用回溯来解决 N queen 问题,但在编译时它会给出运行时错误(动态堆栈缓冲区溢出)
- 在编译/运行时将字符串文本的原始字节流入/流出Windows(非宽)执行字符集,以及ANSI代码页与UTF-8