繁体   English   中英

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

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

您究竟如何从 class 外部访问私有 static 方法。比如说,我有一个 class

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

现在,我只是调用 print() function 从另一个 function 说:

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

我已经在 inte.net 和 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

让我们假设我们的 function 是 static 为简单起见无效

所以我将在 main.cpp:22 中声明

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

我将前进到带有断点的第 22 行,并将打印我的地址 static function

在 GDB 中,您可以使用print giladStruct::myfuncb giladStruct::myfunc这将返回类似的地址

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

那么你需要set func_p = 0x7fffcf5bf112 ,然后继续运行。

地址会改变,但对于 POC/简单的 hack 这将起作用。

我是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();
}

暂无
暂无

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

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