繁体   English   中英

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM