如何从类外部访问私有静态方法?比如说,我有一个类
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::myfunc
或b 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();
}