Реализация статической функции-члена в C++
Мне было интересно, если статическая функция-член по существу означает, что она получает адрес в памяти во время компиляции и никогда не изменяет его в течение всей программы.
Поэтому это дает нам возможность передавать его в указателях без какого-либо страха, поскольку мы всегда уверены, что мы всегда найдем его в одном и том же месте.
3 ответа
- Используя статическую функцию, вы можете вызвать конструктор, который объявлен как приватный.
Вот код,
#include <iostream> using namespace std; class STATIC { private: STATIC() { cout<<"In Constructor..."<<endl; } public: static void fun() { STATIC a1; } }; int main() { STATIC::fun(); }
Это один из вариантов использования статической функции-члена.
Все функции имеют статические адреса, назначенные им во время компиляции (это немного отличается для динамически загружаемых библиотек). Функция-член (статическая или нет) является стандартной функцией, ее адрес известен во время компиляции. Как еще может работать линкер?
Статическая функция-член - это обычная бесплатная функция с забавным именем. Указатель на функцию совместим с указателем на статическую функцию-член.
Нестатическая функция-член - это функция, которая получает и скрытно скрывает this
параметр в качестве первого параметра. Однако указатель на нестатическую функцию-член несовместим с указателем на функцию.
Чтобы вызвать нестатическую функцию-член с помощью указателя на функцию-член, вам нужно предоставить экземпляр... а также синтаксис довольно странный: (x.*member_ptr)(...)
если x
является ссылкой на объект, или (x->*member_ptr)(...)
если х является указателем.
Указатель на нестатическую функцию-член и указатель на функцию являются несовместимыми типами, и нет переносимого способа преобразования одного в другой. Если вы знаете экземпляр и хотите иметь вызываемый объект для вызова одной из его функций, не являющихся членами, вы можете использовать (с C++11) std::function
упаковка лямбда
#include <functional>
#include <string.h>
#include <iostream>
struct Foo {
int x;
Foo(int x) : x(x) {}
void bar() { std::cout << x << std::endl; }
static void baz() { std::cout << "Here\n"; }
};
int main(int argc, const char *argv[]) {
void (Foo::*f)() = &Foo::bar; // Non-static function member pointer
void (*g)() = &Foo::baz; // Static member function = function
Foo x(42);
(x.*f)(); // Prints 42
g(); // Prints "Here"
// Portable way to call a non-static member function just using ff()
std::function<void()> ff = [&x](){ x.bar(); };
ff(); // Prints 42 too
// Hack zone... just to show that on many compilers
// even a pointer to non-static member function is just
// a pointer to a function that accepts however `this`
// as an extra first parameter.
void (*hack)(void *);
memcpy(&hack, &f, sizeof(hack));
hack(&x); // Prints 42 too on g++/clang++ (NOT PORTABLE!!)
return 0;
}