![](/img/trans.png)
[英]Explicitly access static member variable in static member method - in 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 -所以,如果方法没有参数(实际上是一个这样 ),我们可以直接使用__fastcall为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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.