Вызов частного метода в C ++

Это чисто теоретический вопрос, я знаю, что если кто-то объявит метод приватным, вы, вероятно, не должны его называть. Мне удалось вызвать частные виртуальные методы и изменить частные члены для экземпляров, но я не могу понять, как вызвать частный не виртуальный метод (без использования __asm ). Есть ли способ получить указатель на метод? Есть ли другие способы сделать это?

EDIT: я не хочу менять определение classа! Мне просто нужен хак / обходной путь. 🙂

#include заголовочный файл, но:

 #define private public #define class struct 

Понятно, что вам нужно обойти различные охранники и т. Д. И сделать это в изолированном блоке компиляции.

РЕДАКТИРОВАТЬ: Все еще хакерский, но в меньшей степени:

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

См. Мой блог . Я переставляю код здесь

 template struct result { /* export it ... */ typedef typename Tag::type type; static type ptr; }; template typename result::type result::ptr; template struct rob : result { /* fill it ... */ struct filler { filler() { result::ptr = p; } }; static filler filler_obj; }; template typename rob::filler rob::filler_obj; 

Некоторые classы с частными членами

 struct A { private: void f() { std::cout << "proof!" << std::endl; } }; 

И как получить к ним доступ

 struct Af { typedef void(A::*type)(); }; template class rob; int main() { A a; (a.*result::ptr)(); } 

Его можно вызвать, если public функция возвращает адрес private функции, тогда любой может использовать этот адрес для вызова частной функции.

Пример,

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

Вывод:

 private function gets called 

Демо на идее: http://www.ideone.com/zkAw3

У вас есть classы и функции друзей .

Я знаю, что если кто-то объявит метод закрытым, вы, вероятно, не должны его называть.

Дело не в том, «вы не должны его называть», это просто «вы не можете его назвать». Что вы пытаетесь сделать?

Самый простой способ:

 #define private public #define protected public 

Вызвать частный метод из публичной функции того же classа.

Последующий ответ на ответ TED: Не редактируйте заголовок. Вместо этого создайте свою личную копию заголовка и вставьте некоторые объявления friend в эту фиктивную копию заголовка. В вашем источнике #include этот фиктивный заголовок, а не реальный. Вуаля!

Изменение конфиденциальности для общественности может изменить слабые символы, которые являются результатом встроенных методов, что, в свою очередь, может заставить компоновщика жаловаться. Слабые символы, которые являются результатом встроенных методов, будут иметь одинаковые подписи с фальшивыми и реальными заголовками, если все, что делается, это добавить некоторые объявления друзей. С помощью этих объявлений друзей вы можете теперь делать все виды злых дел с помощью такого classа, как доступ к личным данным и вызов частных членов.

добавление
Этот подход не будет работать, если рассматриваемый заголовок использует #pragma once вместо #include guard, чтобы гарантировать, что заголовок является идемпотентным.

Ну, очевидным способом было бы изменить код, чтобы он больше не был закрыт.

Если вы настаиваете на том, чтобы найти злой способ сделать это … ну … с некоторыми компиляторами он может работать, создайте свою собственную версию файла заголовка, где этот метод является public а не private . У зла есть противный способ отскока на вас, хотя (поэтому мы называем это «злым»).

Я думаю, что самое близкое, что вы доберетесь до взлома , это , но это не просто неразумное, но неопределенное поведение, поэтому у него нет семантики. Если это произойдет, чтобы функционировать так, как вы хотите, для любого вызова одной программы, то это чистый шанс.

Определите аналогичный class, который является тем же, что и функция, являющаяся открытой.

Затем выведите объект с частной функцией в функцию с публичной функцией, затем вы можете вызвать публичную функцию.

Если мы говорим о MSVC, я думаю, что самый простой способ без другого вреда, чем сам вызов частного метода, – это большой __asm:

 class A { private: void TestA () {}; }; A a; __asm { // MSVC assumes (this) to be in the ecx. // We cannot use mov since (a) is located on the stack // (ie [ebp + ...] or [esp - ...]) lea ecx, [a] call A::TestA } 

Для GCC это можно сделать, используя искаженное имя функции.

 #include  class A { public: A() { f(); //the function should be used somewhere to force gcc to generate it } private: void f() { printf("\nf"); } }; typedef void(A::*TF)(); union U { TF f; size_t i; }; int main(/*int argc, char *argv[]*/) { A a; //af(); //error U u; //uf = &A::f; //error //load effective address of the function asm("lea %0, _ZN1A1fEv" : "=r" (ui)); (a.*uf)(); return 0; } 

Mangled имена могут быть найдены в файлах nm * .o.

Добавить -masm = опция компилятора Intel

Источники: ошибка GCC: нельзя применять offsetof для функции-члена MyClass :: MyFunction https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

  • Расчет суммы углового угла 3D
  • Запрос на ссылку HasMany
  • Можно ли «прыгать» / «пропустить» в отладчике GDB?
  • Каков правильный способ чтения из сокета TCP в C / C ++?
  • MVC HTML Helpers и выражения lambda
  • Почему не указатели инициализируются с помощью NULL по умолчанию?
  • ConfigurationManager.OpenExeConfiguration - загружает неправильный файл?
  • datetime.parse и заставить работать с определенным форматом
  • Почему компилятор C # испускает инструкцию callvirt для вызова метода GetType ()?
  • Как изменить параметры сети (IP-адрес, DNS, WINS, имя хоста) с кодом в C #
  • Как обрабатывать инъекцию зависимостей в приложении WPF / MVVM
  • Давайте будем гением компьютера.