简体   繁体   English

从 class C++ 外部访问私有 static 方法

[英]Access private static method from outside the class C++

How exactly can you access a private static method from outside the class. Say, I have a class您究竟如何从 class 外部访问私有 static 方法。比如说,我有一个 class

    Class ABC {
    private:
        static void print(string str) {
            cout << "It works!!!" << endl;
        }
    };

Now, I just to call print() function say from another function like:现在,我只是调用 print() function 从另一个 function 说:

    void doSomething() {
         string str = "1776a0";
         // Call to print() here
    }

I have searched the inte.net and stackoverflow for such a problem but I couldn't find much.我已经在 inte.net 和 stackoverflow 上搜索过这样的问题,但我找不到太多。 So, please point me in the right direction as to if this is possible or not and if so how to do it.所以,请指出正确的方向,看看这是否可行,如果可行,该怎么做。

I am currently using GCC.我目前使用的是 GCC。

Thank you all in advance.谢谢大家。

You can't. 你不能 That is exactly what private means. 那正是private意思。 If it is intended to be callable from outside the class, make it public . 如果打算从班级外部调用它,请将其public

Instead of making it public you could call it from another function that is publicly accessible. 相反,使之成为public ,你可以从另一个功能可公开访问的调用它。 This other function could either be a public member of ABC , or a friend function. 该其他功能可以是ABC的公共成员,也可以是friend功能。

Both cases require changing the class definition of ABC . 两种情况都需要更改ABC的类定义。

If the other function just does nothing besides call print() then you have achieved the same effect as making print() public. 如果另一个函数除了调用print()之外什么也没做,那么您将获得与公开print()相同的效果。 But presumably print is private for a reason, eg it relies on some preconditions. 但是大概由于某些原因, print是私有的,例如,它依赖于一些先决条件。 You could make the other function allow for that. 您可以允许其他功能。 For example: 例如:

void abc_printer(string printer_name, string str_to_print)
{
    open_printer(printer_name);          
    ABC::print(str);                         
    close_printer();
}

and inside the class definition of ABC : ABC的类定义中:

friend void abc_printer(string, string);

You can if you know the address of function: 您可以知道函数的地址:

typedef void (*funcPtr)();

class beforeABC
{
public:
    static int getRange() 
    {
        char* funcAddr = (char*)&(beforeABC::func);
        char* endAddr = (char*)&(beforeABC::end);
        return endAddr - funcAddr;
    }
    static void func() { };
    static void end() { };
};

class ABC
{
private:
    static void print()
    {
        cout << "It works!!!" << endl;
    }
public:
    static void func() 
    { 
        // does not works without this line. Can someone explain this?
        if(0 == (unsigned long int)&print);
    };
};

int main()
{
    ABC::func();

    funcPtr f = (funcPtr)((char*)&(beforeABC::end) + beforeABC::getRange());
    f();

    return 0;
}    

It is just a hack. 这只是一个hack。 Very unsafe and compiler\\system dependent. 非常不安全,依赖于编译器\\系统。 Do not use it in real projects. 不要在实际项目中使用它。

谢谢,问一个朋友,我发现了另一种方法:通过使doSomething()函数成为ABC类的朋友。

A great hack (just for proof of concept, DO NOT CODE LIKE THIS.:!) is for example put a break point in the context you need for example main.cpp:21一个很棒的 hack(只是为了概念证明,不要像这样编码。:!)例如在你需要的上下文中放置一个断点,例如 main.cpp:21

let us assume our function is static void for simplicty让我们假设我们的 function 是 static 为简单起见无效

so I will declare in main.cpp:22所以我将在 main.cpp:22 中声明

void (*func_p) () = nullptr;
func_p();

I will advance until line 22 with the break point and will print the address of my static function我将前进到带有断点的第 22 行,并将打印我的地址 static function

in GDB you can use print giladStruct::myfunc or b giladStruct::myfunc this will return the address something like在 GDB 中,您可以使用print giladStruct::myfuncb giladStruct::myfunc这将返回类似的地址

{void (void)} 0x7fffcf5bf112 <giladStruct::myfunc()>

then you need to set func_p = 0x7fffcf5bf112 and continue to run.那么你需要set func_p = 0x7fffcf5bf112 ,然后继续运行。

The address will change but for a POC/simple hack this will work.地址会改变,但对于 POC/简单的 hack 这将起作用。

I'm a newcomer to C++, but you can access private static methods via pointers passed as callbacks, which still allows one to assure the methods cannot be called directly. 我是C ++的新手,但是您可以通过作为回调传递的指针访问私有静态方法,这仍然可以确保不能直接调用这些方法。 This can be done without requiring a friend function, since the callback pointer is registered using the constructor of the class. 由于回调指针是使用该类的构造函数注册的,因此无需朋友函数即可完成此操作。 For example, the following would make the "print" method available as a call back, without allowing the direct invocation of the print method: 例如,以下将使“ print”方法可用作回调,而不允许直接调用print方法:

#include <iostream>
using namespace std;

void RegisterCallback(void (* const fn)(void));

class ABC 
{
public:
    ABC() {RegisterCallback((void (*)(void))&ABC::print);}
private:
    static void print(void) 
    {
        cout << "It works!!!" << endl;
    }
};

int main(void)
{
    ABC abc;
    return 0;
}

void RegisterCallback(void (* const fn)(void))
{
    fn();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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