Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/21: Рейтинг темы: голосов - 21, средняя оценка - 4.71
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
1

Вызов метода класса по его имени в строке

08.08.2020, 15:09. Показов 3958. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Приветствую всех. Был у меня разговор с Делфи-разработчиком и он говорит, что в С++ нет RTTI, в отличие от Делфи. Я говорю, как же нет, если об этом куча статей в интернетах! Тогда он сказал: "Как в С++ вызвать метод класса, если его (метода) имя передали в программу в виде текста? В Делфи это делается парой строк кода!"

В связи с этим у меня, собственно, два вопроса:
1. Вызов метода класса описанным выше способом это RTTI или это что-то другое?
2. Возможно ли в "чистом" С++ выполнить вышеуказанную задачу?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.08.2020, 15:09
Ответы с готовыми решениями:

Вызов класса по его имени
Есть такая задача, из вне приходит строка которая равна имени класса, нужно как-то заставить...

Создание объекта класса и вызов его метода
Добрый день, форумчане. На Яве программирую не больше недели. Столкнулся со следующей проблемой....

Полиморфизм: вызов метода базового класса, переопределенного метода и нового метода
В базовом классе метод помечен как virtual. Насколько я понял из книги: override означает, что...

Вызов методов классов друг у друга (вызов метода из другого класса)
Есть несколько классов, которые могут вызывать методы (функции) друг у друга. Логика: класс1 имеет...

16
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
08.08.2020, 16:55 2
Цитата Сообщение от d7d1cd Посмотреть сообщение
1. Вызов метода класса описанным выше способом это RTTI или это что-то другое?
RTTI не имеет к методам никакого отношения, оно служит для идентификации типов
Цитата Сообщение от d7d1cd Посмотреть сообщение
2. Возможно ли в "чистом" С++ выполнить вышеуказанную задачу?
Нет, ты не можешь получить список методов класса
1
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
09.08.2020, 13:54 3
Цитата Сообщение от d7d1cd Посмотреть сообщение
он говорит, что в С++ нет RTTI, в отличие от Делфи.
Разработчик видимо имел в виду Reflection.

Добавлено через 10 минут
Цитата Сообщение от d7d1cd Посмотреть сообщение
"Как в С++ вызвать метод класса, если его (метода) имя передали в программу в виде текста? В Делфи это делается парой строк кода!"
Если бы это можно было бы сделать так, как это делается в Delphi, то в С++ пришлось бы хранить информацию о методах в runtime. При дизайне языка от этого намеренно отказались, чтобы не нарушать "zero-overhead principle"
Цитата Сообщение от https://www.stroustrup.com/ETAPS-corrected-draft.pdf
What you don’t use, you don’t pay for [BS94]. And further: What you do use, you couldn’t hand code any better.
А вот чего реально в C++ порой не хватает, так это сompile-time рефлексии. Но попытки изменить это есть:
http://www.open-std.org/jtc1/s... 16/p0385r0
2
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.08.2020, 16:42 4
А что в Pascal- есть рефлексия?
Как бы если подумать то в С++Qt есть некие возможности по вызову метода по его имени.

Я к тому не особо понятна имея сравнивать Delphi/VCL и "чистый" С++.
1
369 / 312 / 65
Регистрация: 14.10.2014
Сообщений: 1,319
09.08.2020, 20:00 5
Вообще, смотрел как то с годик назад видео, про С++11 кажется, и там было сказано, что попытки прикрутить рефлексию к С++ (наподобие джавишной к примеру) были предприняты. Причем ни кем-нибудь, а самим комитетом по стандартизации языка, но получалось как то "криво, косо и вообще не очень." С++ это про высокую оптимизацию и быстродействие, а в той же джаве, чтоб пользоваться рефлексией, нужно в классе таскать дополнительную инфу про класс. Это доп расходы. К тому же - что джава, что сишарп (в нем тоже вроде как рефлексия есть) - они чисто объектно ориентированные языки. А С++ - нет. Для сомневающихся - попробуйте сделать в той же джаве что - нибудь вообще без классов - это невозможно, а в плюсах - да без проблем.

Добавлено через 6 минут
Цитата Сообщение от d7d1cd Посмотреть сообщение
Возможно ли в "чистом" С++ выполнить вышеуказанную задачу?
а в чём проблема - передаём название метода через командную строку, сочиняем метод, где разбираем аргументы командной строки, если встретились названия методов, то вызываем их
1
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
10.08.2020, 21:21 6

Не по теме:

Цитата Сообщение от Recrut_rf Посмотреть сообщение
а в чём проблема - передаём название метода через командную строку, сочиняем метод, где разбираем аргументы командной строки, если встретились названия методов, то вызываем их
Что за бред ...



Добавлено через 34 секунды
Цитата Сообщение от d7d1cd Посмотреть сообщение
2. Возможно ли в "чистом" С++ выполнить вышеуказанную задачу?
Конечно можно, но не парой строчек.
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
11.08.2020, 08:05  [ТС] 7

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
Что за бред ...



Цитата Сообщение от Avazart Посмотреть сообщение
Конечно можно, но не парой строчек.
А можете показать как это делается?
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
11.08.2020, 10:30 8
d7d1cd, нужно регистрировать методы руками в каком-то ассоциативном хранилище. Потом можете вызывать по имени.
Автоматически зарегистрировать не получится.

Добавлено через 44 секунды
Была бы статическая рефлексия - можно было бы на ее основе сделать удобную динамическую.
0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.08.2020, 17:17 9
Цитата Сообщение от d7d1cd Посмотреть сообщение
А можете показать как это делается?
Если на коленке то как то так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <functional>
#include <map>
#include <any>
 
using namespace std;
 
template<typename T>
class Meta
{
        
   public:
        template <typename R,typename  ... Args> 
        R invokeMethod(T* object,const std::string& methodName, Args ... args)
        {
           using MethodType = R(T::*)(Args ... args);
           MethodType method= std::any_cast<MethodType>(methods_.at(methodName));
           return std::invoke(method,*object,std::forward<Args>(args)...);
        }
        
        template<typename M>
        void registerMethod(const std::string& methodName, M method)
        {
           methods_[methodName] = method;
        }
        
        bool empty() const { return methods_.empty(); };
        
   private: 
        std::unordered_map<std::string,std::any> methods_;
};
 
 
class Test
{
    public:
        void test1() {  std::cout<< "test1()" << std::endl; }
        void test2() {  std::cout<< "test2()" << std::endl; }
        
        int sqr(int i) { return i*i; }
        double sum(double a,double b){ return a+b; }                          
                          
        static Meta<Test>& meta()
        {
          static Meta<Test> meta_;
          if(meta_.empty())
          {
            meta_.registerMethod("test1",&Test::test1);
            meta_.registerMethod("test2",&Test::test2);
            meta_.registerMethod("sqr"  ,&Test::sqr);
            meta_.registerMethod("sum"  ,&Test::sum);   
          }
          return meta_;
        }
};
 
int main()
{
    Test t;
    try
    {
        Test::meta().invokeMethod<void>(&t,"test1");
        Test::meta().invokeMethod<void>(&t,"test2");
        std::cout<< Test::meta().invokeMethod<int>(&t,"sqr", 10)<< std::endl;
        std::cout<< Test::meta().invokeMethod<double>(&t,"sum", 1.2,0.9)<< std::endl;
    }
    catch(const std::bad_any_cast& e)
    {
        std::cout <<"Wrong method type/signature! " <<e.what() << '\n';
    }
    catch(std::out_of_range& e)
    {
        std::cout <<"Wrong method name! "<<e.what() << '\n'; 
    }
}
1
369 / 312 / 65
Регистрация: 14.10.2014
Сообщений: 1,319
11.08.2020, 19:19 10
Цитата Сообщение от Avazart Посмотреть сообщение
Что за бред ...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <string.h>
 
 
using namespace std;
 
class A
{
public:
    void funcA()
    {
        cout << "A::funcA()\n";
    }
};
 
int main(int argc, char** argv)
{
    A a;
 
    for (int i = 0; i < argc; ++i)
    {
        cout << "  argv[" << i << "]   "
            << argv[i] << "\n";
 
        if (strcmp(argv[i], "A::funcA()") == 0)
            a.funcA();
    }
 
    system("pause");  
    return 0;
}
Цитата Сообщение от d7d1cd Посмотреть сообщение
Как в С++ вызвать метод класса, если его (метода) имя передали в программу в виде текста?
Вызываем скомпилированную прогу в консоли и передаём ей в качестве аргумента строку A::funcA() - получаем вызов нужного метода класса. Можно передать аргумент в main и через среду разработки.
Формально - все условия соблюдены
0
Avazart
11.08.2020, 19:33
  #11

Не по теме:

Recrut_rf, Это был не совсем вопрос ...

0
Recrut_rf
11.08.2020, 19:43
  #12

Не по теме:


Цитата Сообщение от Avazart Посмотреть сообщение
Это был не совсем вопрос ...
Я понимаю, что ТС имел ввиду совершенно другое и то что я изобразил не то что ему нужно, но опять же - имя метода можно передать в программу в виде текста - да можно, а вызвать метод с таким именем - да без проблем. Настоящей рефлексией здесь и не пахнет, но смею предположить, что можно попробовать написать свой "костыль" на тему на чистых плюсах.

0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.08.2020, 19:51 13

Не по теме:

Цитата Сообщение от Recrut_rf Посмотреть сообщение
Я понимаю, что ТС имел ввиду совершенно другое
Т.е. что же это было глупость или намеренное введение в заблуждение?
Или без 5 ржавых никак?



По теме: https://coderoad.ru/4186458/De... 0%BA%D0%B5
0
Recrut_rf
11.08.2020, 19:56
  #14

Не по теме:


Цитата Сообщение от Avazart Посмотреть сообщение
Т.е. что же это было глупость или намеренное введение в заблуждение?
и не глупость и не заблуждение - я просто прочитал вопрос:
Цитата Сообщение от d7d1cd Посмотреть сообщение
Тогда он сказал: "Как в С++ вызвать метод класса, если его (метода) имя передали в программу в виде текста? В Делфи это делается парой строк кода!"
и написал свой ответ, ничего более. Да и дельфист, судя по описанию темы, сам не в курсе, что такое RTTI в С++. Просто я, как скорее всего и вы - знакомы с рефлексией на других языках программирования, поэтому и понимаем, о чём речь идёт. Но вот если бы, к примеру, я никогда бы не писал на Джаве или Сишарпе, то свой ответ (который выше) считал бы абсолютно законным, правильным и истинно верным.

0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.08.2020, 20:05 15
По ссылке выше понятно что в Delphi под RTTI понимают большее чем в С++.

Но в C++ вопрос с рефлексией подымается часто, при чем как писали выше тут еще и рефлексия разная бывает.
Кроме того есть С++Qt и вообще задачи когда такое действительно требуется например при сериализации и GUI.

Другое дело то что разработчики других языков называют благом - для С++ программиста - не всегда оправданные расходы.

Добавлено через 6 минут
Цитата Сообщение от Recrut_rf Посмотреть сообщение
я просто прочитал вопрос:
Где там было сказано что приложение консольное и вообще про аргументы консоли?
0
369 / 312 / 65
Регистрация: 14.10.2014
Сообщений: 1,319
11.08.2020, 20:16 16

Не по теме:


а ведь в С++Qt наверное какие-то зачатки рефлексии имеются. Есть ведь общий предок для многих классов QObject, тот же MOC. Но я не мега специалист по qt, поэтому лучше помолчу. Да и это разговор для отдельной темы



Добавлено через 5 минут
Цитата Сообщение от Avazart Посмотреть сообщение
Где там было сказано что приложение консольное и вообще про аргументы консоли?
А там и обратного не сказано. Да и никто не мешает взять строку с названием метода с графического интерфейса, с поля ввода текста к примеру, и провернуть тот же трюк. Какой вопрос - такой и ответ.
Но так мы сейчас "засрём" тему своими сообщениями - понятно, что я не прав - нет никакой рефлексии в чистых плюсах. И вывод метода класса по имени этого метода - невозможен.
0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.08.2020, 21:14 17
Цитата Сообщение от Recrut_rf Посмотреть сообщение
А там и обратного не сказано.
Так там и про "Капитал" К.Маркса ничего не сказано почему Вы его не упомянули ?

Добавлено через 2 минуты
Цитата Сообщение от Recrut_rf Посмотреть сообщение
а ведь в С++Qt наверное какие-то зачатки рефлексии имеются. Есть ведь общий предок для многих классов QObject, тот же MOC. Но я не мега специалист по qt, поэтому лучше помолчу. Да и это разговор для отдельной темы
Конечно обычно через специальный препроцессинг / кодогенерацию и решается проблема.
В Delphi думаю есть вероятность что примерно так же решается проблема только все намертво зашито в компилятор/IDE.
0
11.08.2020, 21:14
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.08.2020, 21:14
Помогаю со студенческими работами здесь

Вызов метода по имени
Всем привет! Я задался одним очень странным вопросом. У меня есть данные в определенном формате....

Вызов метода по имени
Подскажите как вызвать метод по его имени . Просто допустим что у меня приходят данные от сервера...

Вызов метода агрегата из метода агрегируемого класса
Есть класс-агрегат Game function Game() { this.game_map = null; // другие члены } ...

Вызов метода класса из метода другого класса
Помогите школнегу Имеется несколько классов class Com { protected: unsigned char bufrd,...

Вызов метода по имени из переменной
собственно код: &lt;?php $gg = new init(); $gg -&gt; call(); //class1 class init { function...

Вызов метода производного класса через обращение к методу базового класса
Добрый день. Изучаю основы ООП, наткнулся на проблему. Если создавать классы внутри main.cpp,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru