Как вызвать функцию класса из переменной?
Подскажите пожалуйста, каким образом, можно в C++ сохранить функцию класса в переменную, и затем вызвать её из основного тела программы? Если делать всё просто в main, без разделение на классы, то всё работает. Я же хочу сделать именно в разных файлах.
Как бы я не пытался придумать, у меня выходит ошибка:
non-standard syntax; use '&' to create a pointer to member
Пробую как-то так:
//Class.h: class Class < public: typedef void(Class::*funcType)(); funcType func; void test(); >; //Class.cpp: #include "Class.h" #include Class::Class() < func = Class::test; >void Class::test() < std::cout //Program.cpp #include #include "Class.h" void mian()
Отслеживать
задан 5 июн 2019 в 11:21
3 1 1 бронзовый знак
К тому же указатель на метод немного отличается от указателя на функцию. Ему нужен объект, к которому этот указатель на метод мы можем применить. И тогда получится такая штука (c.*c.func)();
5 июн 2019 в 11:49
Пробовал ставить * и & в различных комбинациях, это не изменяло ошибку. Что-то не пойму, как использовать (c.*c.func)
Как вызвать функцию из класса c
Допустим есть класс EDU и внутри него есть функция Work(. )
Она объявлена как static и определена с ключевым словом inline
Сам класс и функция Work объявлены и описаны в HDR.H
Допустим в SRC.CPP я вызываю функцию EDU::Work (. ) без создания экземпляра класса.
И возникают такие вопросы:
1. Можно ли было вызывать эту функцию если она не была бы static?
2. Что дает слово inline в описании функции в HDR.H ?
3. Получается, что вызвав эту функцию Work автоматически вызывается конструктор класса, где я могу инициализировать его переменные, которые использую в функции Work хотя экземпляр класса EDU при этом не создается, так получается?
Белик Виталий :)
Регистрация: 23.07.2007
Сообщений: 57,792
| Можно ли было вызывать эту функцию если она не была бы static? |
Я бы на это не надеялся.
На то он и статик.
| Что дает слово inline |
| Получается, что |
Почему? Конструктор запускается, когда классу отводится память. Если ты вызываешь статический метод, то сомневаюсь что конструктор отработает. По крайней мере это нонсенс.
I'm learning to live.
Регистрация: 15.02.2010
Сообщений: 15,655
| 1. Можно ли было вызывать эту функцию если она не была бы static? |
Вызывать когда и как? Просто так без создания объекта - нет. Как функцию объекта вполне.
| 3. Получается, что вызвав эту функцию Work автоматически вызывается конструктор класса |
Нет, не вызывается. На то она и функция без объекта.
| где я могу инициализировать его переменные, которые использую в функции Work хотя экземпляр класса EDU при этом не создается |
Нет, не можете, если они не статические. Кто под них память выделит и прочее?
Белик Виталий :)
Регистрация: 23.07.2007
Сообщений: 57,792
| Как функцию объекта вполне. |
Всмысле как функцию класса? Объект-то не создан жеж.
I'm learning to live.
Форумчанин
Регистрация: 01.06.2015
Сообщений: 497
Статик функция отличается тем, что в нее не поступает указатель на объект класса, т.е. this.
Сообщение от Stilet
Всмысле как функцию класса? Объект-то не создан жеж.
class TempClass < int a; public: TempClass():a(10)<>int Get10()< return this->a; // this, о котором я говорил > static int Get20() < return 20; >>;
cout
Но статик функции можно вызывать и с объектов класса:
TempClass tempClass; cout
Если помог, буду очень благодарен за Ваш отзыв (весы в левой нижней части сообщения).
Последний раз редактировалось Krasiosoft; 16.07.2015 в 17:31 .
| Krasiosoft |
| Посмотреть профиль |
| Найти ещё сообщения от Krasiosoft |
Регистрация: 19.08.2009
Сообщений: 2,120
1. Можно ли было вызывать эту функцию если она не была бы static?
если очень хочется, то вызвать можно.
((EDU*)0)->Work();
на этом программа всё Ж)
2. Что дает слово inline в описании функции в HDR.H ?
рекомендация подставить тело функции в точку вызова
компилятор может последовать рекомендации, а может и в пешее эротическое отправить - они сейчас фибко умные, и без программиста знают как лучше поступить.
3. Получается, что вызвав эту функцию Work автоматически вызывается конструктор класса, где я могу инициализировать его переменные, которые использую в функции Work хотя экземпляр класса EDU при этом не создается, так получается?
ничего ты с переменными сделать не можешь.
функции не передается скрытый параметр this и она не получает доступ к данным класса (но может обращаться к статическим даным)
А вы почему со мной не соглашаетесь, у вас что, импотенция? (c) ACE Valery
Форумчанин
Регистрация: 24.11.2012
Сообщений: 495
Сообщение от robix
1. Можно ли было вызывать эту функцию если она не была бы static?
2. Что дает слово inline в описании функции в HDR.H ?
3. Получается, что вызвав эту функцию Work автоматически вызывается конструктор класса, где я могу инициализировать его переменные, которые использую в функции Work хотя экземпляр класса EDU при этом не создается, так получается?
1. Класс - это тоже самое, что структура без функций, имеют одинаковый объём, благодаря чему, можно путём "хитрожопости", получить доступ даже к приват переменным. А вот функции хранятся отдельно, поскольку всё это преобразуется в машинный код, который об объектах ничего не знает. Им выдаётся очень длинное имя и вызывается так как вы установили в соглашениях об вызовах.
2. inline - устарела. компилятор найдя эту функцию старается вставить вместо ссылки на функцию, само тело функции, ну это в общих чертах, не факт, что будет быстро, но на функции длиной в менее 4 строчек или обёрток, почему бы и нет. Все заголовочные данные объявляются в заголовочном файле, вопрос не уместен.
3.Класс сам создаёт свои переменные при помощи описанного Вами конструктора и уничтожается посредством деструктора, морочить голову этим не зачем.
P.S. статик функции неприкольны, использование переменных класса невозможно, не конечно можно, но такие темки крутят, только при создании своих "Окон"
Если помог, тут весы есть , Вам не сложно, а мне приятно.
Последний раз редактировалось Perchik71; 16.07.2015 в 17:47 .
Функции (C++)
Функции — это блоки кода, выполняющие определенные операции. Если требуется, функция может определять входные параметры, позволяющие вызывающим объектам передавать ей аргументы. При необходимости функция также может возвращать значение как выходное. Функции полезны для инкапсуляции основных операций в едином блоке, который может многократно использоваться. В идеальном случае имя этого блока должно четко описывать назначение функции. Следующая функция принимает два целых числа из вызывающего средства и возвращает их сумму; a и b — это параметры типа int .
int sum(int a, int b)
Функция может вызываться или вызываться из любого количества мест в программе. Значения, передаваемые функции, являются аргументами, типы которых должны быть совместимы с типами параметров в определении функции.
int main() < int i = sum(10, 32); int j = sum(i, 66); cout
Нет практического ограничения на длину функции, но хороший дизайн предназначен для функций, выполняющих одну хорошо определенную задачу. Сложные алгоритмы лучше разбивать на более короткие и простые для понимания функции, если это возможно.
Функции, определенные в области видимости класса, называются функциями-членами. В C++, в отличие от других языков, функции можно также определять в области видимости пространства имен (включая неявное глобальное пространство имен). Такие функции называются бесплатными или не-членными функциями; они широко используются в стандартной библиотеке.
Функции могут быть перегружены, что означает, что разные версии функции могут совместно использовать одно и то же имя, если они отличаются числом и /или типом формальных параметров. Дополнительные сведения см. в разделе "Перегрузка функций".
Части объявления функции
Минимальное объявление функции состоит из возвращаемого типа, имени функции и списка параметров (которые могут быть пустыми), а также необязательных ключевое слово, которые предоставляют дополнительные инструкции компилятору. В следующем примере представлено объявление функции:
int sum(int a, int b);
Определение функции состоит из объявления, а также текста, который представляет собой весь код между фигурными скобками:
int sum(int a, int b)
Объявление функции, за которым следует точка с запятой, может многократно встречаться в разных местах кода программы. Оно необходимо перед любыми вызовами этой функции в каждой записи преобразования. По правилу одного определения, определение функции должно фигурировать в коде программы лишь один раз.
При объявлении функции необходимо указать:
- Возвращаемый тип, указывающий тип значения, возвращаемого функцией, или void если значение не возвращается. В C++11 является допустимым типом возвращаемого значения, auto который указывает компилятору выводить тип из инструкции return. В C++14 decltype(auto) также разрешено. Дополнительные сведения см. в подразделе "Выведение возвращаемых типов" ниже.
- Имя функции, которое должно начинаться с буквы или подчеркивания и не может содержать пробелы. Как правило, ведущие подчеркивания в именах функций стандартной библиотеки указывают на частные функции-члены или функции, не являющиеся членами, которые не предназначены для использования в коде.
- Список параметров, заключенный в скобки. В этом списке через запятую указывается нужное (возможно, нулевое) число параметров, задающих тип и, при необходимости, локальное имя, по которому к значениям можно получить доступ в теле функции.
Необязательные элементы объявления функции:
-
constexpr — указывает, что возвращаемое значение функции является константой, значение которой может быть определено во время компиляции.
constexpr float exp(float x, int n) < return n == 0 ? 1 : n % 2 == 0 ? exp(x * x, n / 2) : exp(x * x, (n - 1) / 2) * x; >;
//Declare printf with C linkage. extern "C" int printf( const char *fmt, . );
inline double Account::GetBalance()
#include template T copy_object(T& obj) noexcept(std::is_pod)
Определения функций
Определение функции состоит из объявления и текста функции, заключенного в фигурные скобки, которые содержат объявления переменных, операторы и выражения. В следующем примере показано полное определение функции:
int foo(int i, std::string s) < int value ; MyClass mc; if(strcmp(s, "default") != 0) < value = mc.do_something(i); >return value; >
Переменные, объявленные в теле функции, называются локальными. Они исчезают из области видимости при выходе из функции, поэтому функция никогда не должна возвращать ссылку на локальную переменную.
MyClass& boom(int i, std::string s) < int value ; MyClass mc; mc.Initialize(i,s); return mc; >
функции const и constexpr
Можно объявить функцию-член, чтобы const указать, что функция не может изменять значения элементов данных в классе. Объявив функцию-член как const , компилятор помогает обеспечить правильность константа. Если кто-то ошибочно пытается изменить объект с помощью функции, объявленной как const , возникает ошибка компилятора. Дополнительные сведения см. в разделе const.
Объявите функцию, как constexpr когда значение, которое он создает, может быть определено во время компиляции. Функция constexpr обычно выполняется быстрее, чем обычная функция. Дополнительные сведения см. в разделе constexpr .
Шаблоны функций
Шаблоны функций подобны шаблонам классов. Их задача заключается в создании конкретных функций на основе аргументов шаблонов. Во многих случаях шаблоны могут определять типы аргументов, поэтому их не требуется явно указывать.
template auto Add2(const Lhs& lhs, const Rhs& rhs) < return lhs + rhs; >auto a = Add2(3.13, 2.895); // a is a double auto b = Add2(string< "Hello" >, string< " World" >); // b is a std::string
Дополнительные сведения см. в разделе "Шаблоны функций"
Параметры и аргументы функций
У функции имеется список параметров, в котором через запятую перечислено необходимое (возможно, нулевое) число типов. Каждому параметру присваивается имя, по которому к нему можно получить доступ в теле функции. Шаблон функции может указывать дополнительные параметры типа или значения. Вызывающий объект передает аргументы, представляющие собой конкретные значения, типы которых совместимы со списком параметров.
По умолчанию аргументы передаются функции по значению, то есть функция получает копию передаваемого объекта. Для больших объектов копирование может быть дорогостоящим и не всегда требуется. Чтобы привести к передаче аргументов по ссылке (в частности, ссылке lvalue), добавьте к параметру квантификатор ссылок:
void DoSomething(std::string& input)
Если функция изменяет аргумент, передаваемый по ссылке, изменяется исходный объект, а не его локальная копия. Чтобы предотвратить изменение такого аргумента функции, квалифицируйте параметр как const&:
void DoSomething(const std::string& input)
C++11. Чтобы явно обрабатывать аргументы, передаваемые rvalue-reference или lvalue-reference, используйте двойной амперсанд для параметра, чтобы указать универсальную ссылку:
void DoSomething(const std::string&& input)
Функция, объявленная с одним ключевое слово void в списке объявлений параметров, не принимает аргументов, если ключевое слово void является первым и единственным членом списка объявлений аргументов. Аргументы типа void в другом месте списка создают ошибки. Например:
// OK same as GetTickCount() long GetTickCount( void );
Хотя это недопустимо указывать void аргумент, кроме описанного здесь, типы, производные от типа void (например, указателей на void и массивы) могут отображаться в любом месте списка объявлений void аргументов.
Аргументы по умолчанию
Последним параметрам в сигнатуре функции можно назначить аргумент по умолчанию, т. е. вызывающий объект сможет опустить аргумент при вызове функции, если не требуется указать какое-либо другое значение.
int DoSomething(int num, string str, Allocator& alloc = defaultAllocator) < . >// OK both parameters are at end int DoSomethingElse(int num, string str = string< "Working" >, Allocator& alloc = defaultAllocator) < . >// C2548: 'DoMore': missing default parameter for parameter 2 int DoMore(int num = 5, // Not a trailing parameter! string str, Allocator& = defaultAllocator)
Дополнительные сведения см. в разделе "Аргументы по умолчанию".
типов возвращаемых функциями значений;
Функция может не возвращать другую функцию или встроенный массив; однако он может возвращать указатели на эти типы или лямбда-объект, который создает объект функции. За исключением этих случаев, функция может возвращать значение любого типа, который находится в область, или не возвращать никакого значения, в этом случае возвращаемый тип. void
Завершающие возвращаемые типы
"Обычные" возвращаемые типы расположены слева от сигнатуры функции. Конечный возвращаемый тип находится в правой части подписи и предшествует оператору -> . Завершающие возвращаемые типы особенно полезны в шаблонах функций, когда тип возвращаемого значения зависит от параметров шаблона.
template auto Add(const Lhs& lhs, const Rhs& rhs) -> decltype(lhs + rhs)
Если auto используется в сочетании с конечным типом возвращаемого значения, он просто служит заполнителем для любого создаваемого выражения деклтипа и не выполняет вычет типов.
Локальные переменные функции
Переменная, объявленная внутри тела функции, называется локальной переменной или просто локальной . Нестатические локальные локальные параметры отображаются только внутри тела функции, и если они объявлены в стеке выходят из область при выходе функции. При создании локальной переменной и возврате ее по значению компилятор обычно может выполнять оптимизацию именованных возвращаемых значений, чтобы избежать ненужных операций копирования. Если локальная переменная возвращается по ссылке, компилятор выдаст предупреждение, поскольку любые попытки вызывающего объекта использовать эту ссылку произойдут после уничтожения локальной переменной.
В C++ локальные переменные можно объявлять как статические. Переменная является видимой только в теле функции, однако для всех экземпляров функции существует только одна копия переменной. Локальные статические объекты удаляются во время завершения, определенного директивой atexit . Если статический объект не был создан, так как поток управления программы обошел его объявление, попытка уничтожить этот объект не выполняется.
Вычет типов в возвращаемых типах (C++14)
В C++14 можно использовать auto для указания компилятору выводить тип возвращаемого значения из тела функции, не предоставляя конечный тип возвращаемого значения. Обратите внимание, что auto всегда дедуцирует возвращаемое значение. Используйте auto&& , чтобы дать компилятору команду выведения ссылки.
В этом примере auto будет выведено в виде копии неконстантных значений суммы lhs и rhs.
template auto Add2(const Lhs& lhs, const Rhs& rhs) < return lhs + rhs; //returns a non-const object by value >
Обратите внимание, что auto не сохраняет константность типа, который он выводит. Для переадресации функций, возвращаемые значением которых необходимо сохранить констант-ness или ref-ness его аргументов, можно использовать decltype(auto) ключевое слово, которая использует decltype правила вывода типов и сохраняет все сведения о типе. decltype(auto) может использоваться в качестве обычного возвращаемого значения слева или в качестве возвращаемого значения.
В следующем примере (на основе кода из N3493) показано decltype(auto) , что используется для обеспечения идеальной пересылки аргументов функций в возвращаемом типе, который не известен до создания шаблона.
template, int. I> decltype(auto) apply_(F&& f, Tuple&& args, index_sequence) < return std::forward(f)(std::get(std::forward(args)). ); > template, typename Indices = make_index_sequence> decltype( auto) apply(F&& f, Tuple&& args) < return apply_(std::forward(f), std::forward(args), Indices()); >
Возврат нескольких значений из функции
Существует несколько способов возврата нескольких значений из функции:
-
Инкапсулируйте значения в именованном классе или объекте структуры. Требуется, чтобы определение класса или структуры отображалось вызывающей объекту:
#include #include using namespace std; struct S < string name; int num; >; S g() < string t< "hello" >; int u< 42 >; return < t, u >; > int main()
#include #include #include using namespace std; tuple f() < int i< 108 >; string s< "Some text" >; double d< .01 >; return < i,s,d >; > int main() < auto t = f(); cout (t) (t) (t)#include #include #include using namespace std; tuple f() < int i< 108 >; string s< "Some text" >; double d< .01 >; return < i,s,d >; > struct S < string name; int num; >; S g() < string t< "hello" >; int u< 42 >; return < t, u >; > int main() < auto[x, y, z] = f(); // init from tuple coutУказатели функций
Как и в C, в C++ поддерживаются указатели на функции. Однако более типобезопасной альтернативой обычно служит использование объекта-функции.
Рекомендуется typedef объявить псевдоним для типа указателя функции при объявлении функции, возвращающей тип указателя функции. Например.
typedef int (*fp)(int); fp myFunction(char* s); // function returning function pointerЕсли это не сделано, правильный синтаксис объявления функции может быть выведен из синтаксиса декларатора для указателя функции, заменив идентификатор ( fp в приведенном выше примере) именем функций и списком аргументов следующим образом:
int (*myFunction(char* s))(int);Предыдущее объявление эквивалентно объявлению, используемому typedef ранее.
8.15. Вызов виртуальной функции родительского класса
Требуется вызвать функцию родительского класса, но она переопределена в производном классе, так что обычный синтаксис p->method() не дает нужного результата.
Укажите полное имя вызываемого метода, включая имя родительского или базового класса (если есть только два класса, например). (См. пример 8.16.)
Пример 8.16. Вызов определенной версии виртуальной функции
using namespace std;
virtual void foo()
class Derived : public Base
virtual void foo()
Derived* p = new Derived();
p->foo(); // Вызов версии производного класса
p->Base::foo(); // Вызов версии базового класса
Регулярное использование переопределения полиморфных возможностей C++ является плохой идеей, но иногда это требуется сделать. Как и в случае с большинством других методик С++, это по большей части вопрос синтаксиса. Когда требуется вызвать определенную версию виртуальной функции базового класса, просто укажите ее имя после имени этого класса, как это сделано в примере 8.16.
Здесь будет вызвана версия foo, определенная в Base, а не та, которая определена в каком-то из подклассов Base, на который указывает p.
Читайте также
Пример кода родительского процесса
Пример кода родительского процесса #include <stdio.h>#include <stdlib.h>#include <string.h>#include <process.h>#include <sys/neutrino.h>#include <sys/netmgr.h>#include <spawn.h>#include <errno.h>#include <unistd.h>#include <sys/wait.h>#include <locale.h>int main(int argc, char **argv) < int nid; // Дескриптор удаленного узла int PChanid; //
Многократный вызов функции connect для сокета UDP
Многократный вызов функции connect для сокета UDP Процесс с присоединенным сокетом UDP может снова вызвать функцию connect Для этого сокета, чтобы:? задать новый IP-адрес и порт;? отсоединить сокет.Первый случай, задание нового собеседника для присоединенного сокета UDP, отличается
Глава 12 Настройка родительского контроля
Глава 12 Настройка родительского контроля 12.1. Ограничения по времени12.2. Игры12.3. Разрешение и блокировка конкретных программВпервые с понятием родительского контроля пользователи столкнулись в операционной системе Windows Vista. Задумка достаточно интересная: вы можете
R.5.2.2 Вызов функции
R.5.2.2 Вызов функции Вызов функции является постфиксным выражением, за которым следует, возможно пустой, список выражений в скобках, разделенных запятой. Эти выражения образуют фактические параметры функции. Постфиксное выражение должно иметь тип "функция, возвращающая T",
R.13.4.4 Вызов функции
R.13.4.4 Вызов функции Вызов функции есть конструкция вида:первичное-выражение ( список-выражений opt )Она считается бинарной операцией, в которой первичное-выражение представляет первый операнд, а список-выражений (возможно пустой), - второй операнд. Именем, задающим функцию,
Правило 23: Предпочитайте функциям-членам функции, не являющиеся ни членами, ни друзьями класса
Правило 23: Предпочитайте функциям-членам функции, не являющиеся ни членами, ни друзьями класса Возьмем класс для представления Web-браузера. В числе прочих такой класс может предлагать функции, который очищают кэш загруженных элементов, очищают историю посещенных URL и
Вызов функции с аргументом: фактические аргументы
Вызов функции с аргументом: фактические аргументы Задача в данном случае состоит в том, чтобы присвоить некоторую величину формальному аргументу number. После того как эта переменная получит свое значение, программа сможет выполнить свою задачу. Мы присваиваем
5.4.2. Взаимодействие родительского и дочернего процессов
5.4.2. Взаимодействие родительского и дочернего процессов Функция pipe() создает два файловых дескриптора, которые действительны только в текущем процессе и его потомках. Эти дескрипторы нельзя передать постороннему процессу. Дочерний процесс получает копии дескрипторов
Вызов функции
Вызов функции Вызов функции передает управление и фактические аргументы (если они есть) заданной функции. Синтаксически вызов функции имеет следующий вид:<выражение>([<список выражений>])<Выражение> вычисляется, и его результат интерпретируется как адрес
Вызов функции с переменным числом аргументов
Вызов функции с переменным числом аргументов Для вызова функции с переменным числом аргументов не требуется никаких специальных действий: в вызове функции просто задается то число аргументов, которое нужно. В предварительном объявлении (если оно есть) переменное число
13.3. Функции-члены класса
13.3. Функции-члены класса Функции-члены реализуют набор операций, применимых к объектам класса. Например, для Screen такой набор состоит из следующих объявленных в нем функций-членов:class Screen char get() < return _screen[_cursor]; >char get( int, int );void move( int, int );bool checkRange( int, int );int
17.5.3. Статический вызов виртуальной функции
17.5.3. Статический вызов виртуальной функции Вызывая виртуальную функцию с помощью оператора разрешения области видимости класса, мы отменяем механизм виртуализации и разрешаем вызов статически, на этапе компиляции. Предположим, что мы определили виртуальную функцию isA()
6.8 Вызов Функции
6.8 Вызов Функции Вызов функции, то есть запись выражение(список_выражний), можно проинтерпретировать как бинарную операцию, и операцию вызова можно перегружать так же, как и другие оперции. Список параметров функции operator() вычисляется и прверяется в соответствие с
Компоненты класса и АТД функции
Компоненты класса и АТД функции Для понимания отношений между утверждениями и АТД необходимо, прежде всего, установить отношение между компонентами класса и их двойниками - АТД функциями. В свете прежних обсуждений функции подразделяются на три категории: создатели,
Практическая работа 60. Настройка родительского контроля
Практическая работа 60. Настройка родительского контроля Задание. Настроить ограничения при использовании компьютера детьми и проверить их работу. ВНИМАНИЕ Это задание можно выполнить только в версиях Windows Vista Home Basic, Home Premium и Ultimate и только при использовании учетной