C++ - 方法/成员访问
C++ - Method/Member access
我们都知道私有方法和成员只能在类内部访问,就像受保护的方法和成员可以在类和从该类派生的类中访问一样。但是它的"访问控制"在哪里?"访问控制"是在编译时发生的,还是编译器在运行时添加额外的机器代码来控制它?
我可以创建一个这样的类吗:
class Print
{
public:
void printPublic();
private:
void printPrivate();
};
int main()
{
Print print;
print.printPublic() // Change this to printPrivate() after compiling the code
return(EXIT_SUCCESS);
}
然后在编译代码后编辑机器代码以调用printPrivate()
而不是printPublic()
方法而没有错误?
一旦你摆弄了机器代码,你就不再是编译C++,而是直接用机器代码编程。
因此,你的问题有些没有实际意义。
您可以将访问说明符视为本质上是编译时指令,但请注意,编译器可以根据它们做出优化选择。换句话说,它可能是其中之一。C++标准也不必对此进行任何说明。
"访问控制"发生在编译时,并且仅适用于C ++代码。 你甚至不需要编辑机器代码 - 你可以轻松地从汇编语言调用私有方法 - 所以这表明这仅适用于C ++限制。 当然,没有任何额外的机器代码在运行时控制它 - 这根本不可能控制谁调用方法。
只需演示. 注意函数名称,它如何损坏取决于 x86 或 x64 编译以及编译器可能 - 我的CL编译器和 x64 平台蝙蝠演示可以轻松更改为 x86 或其他编译器
C++ 代码
class Print
{
public:
void printPublic();
private:
void printPrivate();
};
// must be not inline or referenced from c++ code or will be droped by compiler!
void Print::printPrivate()// thiscall
{
DbgPrint("%s<%p>n", __FUNCTION__, this);
}
void Print::printPublic()// thiscall
{
DbgPrint("%s<%p>n", __FUNCTION__, this);
}
extern "C"
{
// stub impemeted in asm
void __fastcall Print_printPrivate(Print* This);
void __fastcall Print_printPublic(Print* This);
};
Print p;
//p.printPrivate();//error C2248
p.printPublic();
Print_printPrivate(&p);
Print_printPublic(&p);
和 ASM 代码(适用于ML64)
_TEXT segment 'CODE'
extern ?printPrivate@Print@@AEAAXXZ:proc
extern ?printPublic@Print@@QEAAXXZ:proc
Print_printPrivate proc
jmp ?printPrivate@Print@@AEAAXXZ
Print_printPrivate endp
Print_printPublic proc
jmp ?printPublic@Print@@QEAAXXZ
Print_printPublic endp
_TEXT ENDS
END
另请注意,对于 x86,所有 C++ 方法都使用thisCall调用约定 - 第一个参数在 ECX 寄存器中,下一个参数在堆栈中,至于__stdcall- 所以如果方法没有参数(实际上是一个这个),我们可以按原样使用__fastcallfor asm 函数,如果存在参数,我们需要将EDX推送到汇编器存根中的堆栈。 对于 x64 没有这个问题 - 这里只有一个调用约定,但这一切都已经与主要问题无关。
带有额外参数的 x86 代码示例,用于演示如何将__fastcall转换为__thiscall
class Print
{
public:
void printPublic(int a, int b)// thiscall
{
DbgPrint("%s<%p>(%x, %x)n", __FUNCTION__, this, a, b);
}
private:
void printPrivate(int a, int b);
};
// must be not inline or referenced from c++ code or will be droped by compiler!
void Print::printPrivate(int a, int b)// thiscall
{
DbgPrint("%s<%p>(%x, %x)n", __FUNCTION__, this, a, b);
}
extern "C"
{
// stub impemeted in asm
void __fastcall Print_printPrivate(Print* This, int a, int b);
void __fastcall Print_printPublic(Print* This, int a, int b);
};
Print p;
//p.printPrivate(1,2);//error C2248
p.printPublic(1, 2);
Print_printPrivate(&p, 1, 2);
Print_printPublic(&p, 1, 2);
和 ASM
.686p
_TEXT segment
extern ?printPublic@Print@@QAEXHH@Z:proc
extern ?printPrivate@Print@@AAEXHH@Z:proc
@Print_printPrivate@12 proc
xchg [esp],edx
push edx
jmp ?printPrivate@Print@@AAEXHH@Z
@Print_printPrivate@12 endp
@Print_printPublic@12 proc
xchg [esp],edx
push edx
jmp ?printPublic@Print@@QAEXHH@Z
@Print_printPublic@12 endp
_TEXT ends
end
«访问控制»发生在编译时
- 这是关于成员访问规则的正确摘要吗
- 为什么我在空指针错误(链表)中获取成员访问权限
- 成员访问是否在空指针上定义C++?
- C++ IDE 不会推断/自动完成对模板类中的 std::array 下标表达式的成员访问
- 为什么类成员数据必须是静态的才能被模板化类的模板化结构成员访问
- 为什么c++允许成员函数定义中实例的私有成员访问
- C/C++ 包含点的宏参数(成员访问运算符)
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- 内部类私有成员访问和封闭的友好性
- 通过 C++ 中的另一个结构成员访问结构
- 具体化 PRVALUES 成员访问的 decltype 行为不正确
- 常量表达式中的静态成员访问
- XVALUE来自类成员访问表达式
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- 在 c++ 中,为什么 -> 被称为二进制中缀指针成员访问运算符?
- 如何访问模板参数的成员?“成员访问不完整的类型”
- 不明确的可变参数类成员访问
- C 受保护的成员访问
- 将typeID转换为静态成员访问(C )的命名空间