在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:47:27  来源:igfitidea点击:

Calling private method in C++

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

#includethe 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 publicfunction returns the address of the privatefunction, 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

You have friendclasses and functions.

你有朋友类和函数。

I know that if someone declares a method private, you probably shouldn't call it.

我知道如果有人将方法声明为私有,您可能不应该调用它。

The point is not 'you shouldn't call it', it's just 'you cannot call it'. What on earth are you trying to do?

重点不是“你不应该打电话”,而是“你不能打电话”。你到底想做什么?

回答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 frienddeclarations in that bogus copy of the header. In your source, #includethis 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 onceinstead of a #includeguard 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 publicinstead 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.

然后将具有私有函数的对象类型转换为具有公共函数的对象,然后您可以调用公共函数。