从c++类外部访问私有静态方法



如何从类外部访问私有静态方法?比如说,我有一个类

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

现在,我只需调用print()函数比如从另一个函数中调用

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

我已经在互联网和stackoverflow上搜索了这样一个问题,但我找不到太多。所以,请给我指出正确的方向,如果这是可能的还是不可能的,如果是这样的话,怎么做。

我正在使用GCC。

提前感谢大家。

你不能。这就是private的意思。如果想从类外部调用它,则将其设置为public

而不是使它public你可以从另一个函数调用它,公开访问。这个函数可以是ABC的公共成员,也可以是friend函数。

这两种情况都需要更改ABC的类定义。

如果另一个函数除了调用print()之外什么都不做,那么您就获得了与将print()设置为公共相同的效果。但print是私有的是有原因的,例如它依赖于一些先决条件。你可以让另一个函数允许这个。例如:

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

ABC的类定义内:

friend void abc_printer(string, string);

如果您知道函数的地址,则可以:

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;
}    

这只是一个hack。非常不安全且依赖于编译器系统。不要在实际项目中使用。

谢谢,问一个朋友我找到了另一种方法:通过将doSomething()函数设置为类ABC的友元

一个伟大的hack(只是为了证明概念,不要这样写代码!!)比如在需要的上下文中设置一个断点例如main.cpp:21

为简单起见,假设函数为静态void

所以我将在main。cpp:22

中声明
void (*func_p) () = nullptr;
func_p();

我将前进到第22行,其中有断点,并将打印静态函数

的地址GDB中的

可以使用print giladStruct::myfuncb giladStruct::myfunc这将返回类似

这样的地址
{void (void)} 0x7fffcf5bf112 <giladStruct::myfunc()>

则需要set func_p = 0x7fffcf5bf112然后继续运行

地址将改变,但对于POC/简单的黑客这将工作

我是c++的新手,但是您可以通过作为回调传递的指针访问私有静态方法,这仍然允许您确保不能直接调用方法。这可以在不需要友元函数的情况下完成,因为回调指针是使用类的构造函数注册的。例如,下面的代码将使"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();
}

最新更新