在 C++ 中调用私有方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6873138/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling private method in C++
提问by Luchian Grigore
This is purely a theoretical question, I know that if someone declares a method private, you probably shouldn't call it. I managed to call private virtual methods and change private members for instances, but I can't figure out how to call a private non-virtual method (without using __asm
). Is there a way to get the pointer to the method? Are there any other ways to do it?
这纯粹是一个理论问题,我知道如果有人将方法声明为私有,您可能不应该调用它。我设法调用私有虚拟方法并更改实例的私有成员,但我不知道如何调用私有非虚拟方法(不使用__asm
)。有没有办法获得指向该方法的指针?有没有其他方法可以做到?
EDIT: I don't want to change the class definition! I just want a hack/workaround. :)
编辑:我不想更改类定义!我只想要一个黑客/解决方法。:)
采纳答案by Pete
#include
the header file, but:
#include
头文件,但是:
#define private public
#define class struct
Clearly you'll need to get around various inclusion guards etc and do this in an isolated compilation unit.
显然,您需要绕过各种包含保护等,并在隔离的编译单元中执行此操作。
EDIT: Still hackish, but less so:
编辑:仍然是hackish,但不那么:
#include <iostream>
#define private friend class Hack; private
class Foo
{
public:
Foo(int v) : test_(v) {}
private:
void bar();
int test_;
};
#undef private
void Foo::bar() { std::cout << "hello: " << test_ << std::endl; }
class Hack
{
public:
static void bar(Foo& f) {
f.bar();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Foo f(42);
Hack::bar(f);
system("pause");
return 0;
}
回答by Johannes Schaub - litb
See my blog post. I'm reposting the code here
请参阅我的博客文章。我在这里重新发布代码
template<typename Tag>
struct result {
/* export it ... */
typedef typename Tag::type type;
static type ptr;
};
template<typename Tag>
typename result<Tag>::type result<Tag>::ptr;
template<typename Tag, typename Tag::type p>
struct rob : result<Tag> {
/* fill it ... */
struct filler {
filler() { result<Tag>::ptr = p; }
};
static filler filler_obj;
};
template<typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;
Some class with private members
一些带有私有成员的类
struct A {
private:
void f() {
std::cout << "proof!" << std::endl;
}
};
And how to access them
以及如何访问它们
struct Af { typedef void(A::*type)(); };
template class rob<Af, &A::f>;
int main() {
A a;
(a.*result<Af>::ptr)();
}
回答by Nawaz
It can be called if a public
function returns the address of the private
function, then anyone can use that address to invoke the private function.
如果public
函数返回函数的地址private
,则可以调用它,然后任何人都可以使用该地址来调用私有函数。
Example,
例子,
class A
{
void f() { cout << "private function gets called" << endl; }
public:
typedef void (A::*pF)();
pF get() { return &A::f; }
};
int main()
{
A a;
void (A::*pF)() = a.get();
(a.*pF)(); //it invokes the private function!
}
Output:
输出:
private function gets called
Demo at ideone : http://www.ideone.com/zkAw3
ideone 演示:http: //www.ideone.com/zkAw3
回答by Antonio Pérez
回答by legendlee
The simplest way:
最简单的方法:
#define private public
#define protected public
回答by David Hammen
Followup on T.E.D.'s answer: Don't editthe header. Instead create your own private copy of the header and insert some friend
declarations in that bogus copy of the header. In your source, #include
this bogus header rather than the real one. Voila!
对 TED 回答的跟进:不要编辑标题。而是创建您自己的标题的私有副本,并friend
在该标题的伪造副本中插入一些声明。在您的来源中,#include
这个伪造的标题而不是真实的标题。瞧!
Changing private to public might change the weak symbols that result from inlined methods, which in turn might cause the linker to complain. The weak symbols that result from inline methods will have the same signatures with the phony and real headers if all that is done is to add some friend declarations. With those friend declarations you can now do all kinds of evil things with the class such as accessing private data and calling private members.
将 private 更改为 public 可能会更改由内联方法产生的弱符号,这反过来可能会导致链接器抱怨。如果所做的只是添加一些友元声明,那么由内联方法产生的弱符号将具有与虚假和真实标头相同的签名。使用这些友元声明,您现在可以对类做各种邪恶的事情,例如访问私有数据和调用私有成员。
Addendum
This approach won't work if the header in question uses #pragma once
instead of a #include
guard to ensure the header is idempotent.
附录
如果有问题的标头使用#pragma once
而不是#include
保护来确保标头是幂等的,则此方法将不起作用。
回答by ascanio
Call the private method from a public function of the same class.
从同一类的公共函数调用私有方法。
回答by T.E.D.
Well, the obvious way would be to edit the code so that it is no longer private.
嗯,显而易见的方法是编辑代码,使其不再是私有的。
If you insist on finding an evilway to do it...well...with some compilers it may work create your own version of the header file where that one method is public
instead of private
. Evil has a nasty way of rebounding on you though (that's why we call it "evil").
如果您坚持要找到一种邪恶的方法来做到这一点......好吧......使用某些编译器它可能会创建您自己的头文件版本,其中一种方法public
代替private
. 尽管邪恶有一种令人讨厌的反弹方式(这就是我们称其为“邪恶”的原因)。
回答by Lightness Races in Orbit
I think the closest you'll get to a hack is this, but it's not just unwise but undefined behaviourso it has no semantics. If it happens to function the way you want for any single program invocation, then that's pure chance.
我认为最接近 hack 的是 this,但这不仅是不明智的,而且是未定义的行为,因此它没有语义。如果它碰巧以您想要的方式运行任何单个程序调用,那么这就是纯粹的机会。
回答by QuentinUK
Define a similar class that is the same apart from the function being public.
定义一个类似的类,除了函数是公共的之外,它是相同的。
Then typecast an object with the private function to one with the public function, you can then call the public function.
然后将具有私有函数的对象类型转换为具有公共函数的对象,然后您可以调用公共函数。