Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Egor138
32 / 13 / 2
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2
#1

Возвращаемое значение делигата - C++

22.10.2013, 12:57. Просмотров 337. Ответов 9
Метки нет (Все метки)

Сделал делигат, который принимает до 4-х аргументов функции, которая принимает любой из типой для возвращаемого значения.


Вот собственно файл Delegate.h

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
struct VOID{};
class IArgument {public: virtual  ~IArgument(){}};
 
template< class Arg1 = VOID, class Arg2 = VOID, 
          class Arg3 = VOID, class Arg4 = VOID  >
class Argument : public IArgument
{
public: 
    Argument() {}
    Argument(Arg1 arg) : arg1(arg) {}
    Argument(Arg1 _arg1, Arg1 _arg2) : arg1(_arg1), arg2(_arg2) {}
    Argument(Arg1 _arg1, Arg1 _arg2,Arg1 _arg3) : 
                arg1(_arg1), arg2(_arg2),arg3(_arg3) {}
    Argument(Arg1 _arg1, Arg1 _arg2,Arg1 _arg3, Arg1 _arg4) : 
                arg1(_arg1), arg2(_arg2),
                arg3(_arg3), arg4(_arg4) {}
 
    Arg1 arg1, arg2, arg3, arg4;
};
 
 
 
class IContainer {public: virtual void Call(IArgument*) {}};
 
template< class Obj, class Method>
class Container : public IContainer {};
 
//Для вызова без аргумента
template< class Obj, class Ret_Type>
class Container<Obj, Ret_Type (Obj::*)(void)> : public IContainer
{
public:
    typedef Ret_Type (Obj::*Method)(void);
    Container(Obj* v1, Method v2) : val1(v1), val2(v2) {}
 
    void Call(IArgument *arg)
    {
        (val1->*val2)();
    }
 
private:
    Obj *val1;
    Method val2;
};
 
//Для  одного аргумента
template< class Obj, class Ret_Type, class Arg1>
class Container<Obj, Ret_Type (Obj::*)(Arg1)> : public IContainer
{
public:
    typedef Argument<Arg1> Arg_type;
    typedef Ret_Type (Obj::*Method)(Arg1);
    Container(Obj* v1, Method v2) : val1(v1), val2(v2) {}
 
    void Call(IArgument *arg)
    {
        Arg_type* a = dynamic_cast< Arg_type* >( arg );
        (val1->*val2)(a->arg1);
    }
 
private:
    Obj *val1;
    Method val2;
};
 
//Для  двух  аргументов
template< class Obj, class Ret_Type, class Arg1, class Arg2>
class Container<Obj, Ret_Type (Obj::*)(Arg1, Arg2)> : public IContainer
{
public:
    typedef Argument<Arg1, Arg2> Arg_type;
    typedef Ret_Type (Obj::*Method)(Arg1, Arg2);
    Container(Obj* v1, Method v2) : val1(v1), val2(v2) {}
 
    void Call(IArgument *arg)
    {
        Arg_type* a = dynamic_cast< Arg_type* >(arg);
        (val1->*val2)(a->arg1, a->arg2);
    }
 
private:
    Obj *val1;
    Method val2;
};
 
//Для  трех  аргументов
template< class Obj, class Ret_Type, class Arg1, class Arg2, class Arg3>
class Container<Obj, Ret_Type (Obj::*)(Arg1, Arg2, Arg3)> : public IContainer
{
public:
    typedef Argument<Arg1, Arg2, Arg3> Arg_type;
    typedef Ret_Type (Obj::*Method)(Arg1, Arg2, Arg3);
    Container(Obj* v1, Method v2) : val1(v1), val2(v2) {}
 
    void Call(IArgument *arg)
    {
        Arg_type* a = dynamic_cast< Arg_type* >(arg);
        (val1->*val2)(a->arg1, a->arg2, a->arg3);
    }
 
private:
    Obj *val1;
    Method val2;
};
 
//Для  четырех аргументов
template< class Obj, class Ret_Type, class Arg1, class Arg2, class Arg3, class Arg4 >
class Container<Obj, Ret_Type (Obj::*)(Arg1, Arg2, Arg3, Arg4)> : public IContainer
{
public:
    typedef Argument<Arg1, Arg2, Arg3, Arg4> Arg_type;
    typedef Ret_Type (Obj::*Method)(Arg1, Arg2, Arg3, Arg4);
    Container(Obj* v1, Method v2) : val1(v1), val2(v2) {}
 
    void Call(IArgument *arg)
    {
        Arg_type* a = dynamic_cast< Arg_type* >(arg);
        (val1->*val2)(a->arg1, a->arg2, a->arg3, a->arg4);
    }
 
private:
    Obj *val1;
    Method val2;
};
 
 
class Delegate
{
public:
 
    template< class Obj, class Method >
    void Connect(Obj* val1, Method val2)
    {
        p_container = new Container<Obj, Method>(val1, val2);
    }
 
    void operator ()()
    {
        p_container->Call(&Argument<>());
    }
 
    template< class Arg1 >
    void operator ()(Arg1 arg1)
    {
        p_container->Call(& Argument<Arg1>(arg1) );
    }
 
    template< class Arg1, class Arg2 >
    void operator ()(Arg1 arg1, Arg2 arg2)
    {
        p_container->Call(& Argument<Arg1, Arg2>(arg1, arg2) );
    }
 
    template< class Arg1, class Arg2, class Arg3 >
    void operator ()(Arg1 arg1, Arg2 arg2, Arg3 arg3)
    {
        p_container->Call(& Argument<Arg1, Arg2, Arg3>(arg1, arg2, arg3) );
    }
 
    template< class Arg1, class Arg2, class Arg3, class Arg4 >
    void operator ()(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
    {
        p_container->Call(& Argument<Arg1, Arg2, Arg3, Arg4>(arg1, arg2, arg3, arg4) );
    }
 
private:
    IContainer *p_container;
};

Работаю я с ним вот так

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include "Delegate.h"
using namespace std;
 
class Test
{
public:
    int f1() {return 5;}
};
 
int main()
{
    Test t1;
    IDelegate d1;
    d1.Connect(&t1, &Test::f1);
    d1();
    system("pause >void");
}
И собственно вопрос:

Я не пойму как мне вернуть значение функции f1 имеенно в точку d1(); в функции main.
Если я спокойно могу манипулировать этим значением в класса Container, то для того чтобы вернуть его из operator () мне нужно в классе Delegate как то его вытащить. Вот я и не знаю как.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
22.10.2013, 12:57
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Возвращаемое значение делигата (C++):

Возвращаемое значение - C++
Как сделать так, что бы в зависимости от подаваемых аргументов, функция возвращала разные значения? Пробовал через шаблоны, но не...

Значение, возвращаемое функцией (C++) - C++
В общем, задача такая. Написать программу, печатающую все вводимые символы в нижнем регистре. Программа должна использовать цикл while....

Template возвращаемое значение - C++
функция принимает различные типы и делает с ними операцию. И не известно какой тип она должна вернуть. например если пришел int и float,...

Классы. Возвращаемое значение - C++
Всем привет:) Помогите исправить ошибки template &lt;class T&gt; class Vector { private: T *m_data; public: ...

Возвращаемое значение функции - C++
Здравствуйте Я тут новенький. Очень трудно у вас проходить регистрацию. У меня вопрос по С++ Компилятор: Code Blocks ...

Возвращаемое значение из класса - C++
#include &lt;iostream&gt; using namespace std; class Integer { public: int value; Integer(int i) { value = i; } const...

9
Raali
638 / 342 / 42
Регистрация: 06.07.2013
Сообщений: 1,107
Завершенные тесты: 1
22.10.2013, 13:49 #2
нужно чтобы метод Call возвращал значение значит а не был void'ом
даже если он void , то можно возвращать значение в дополнительный параметр при вызове функции, например

C++
1
void Call(IArgument *arg, T* ret)
в ret и будет попадать возвращаемое значение

Добавлено через 5 минут
где T- тип возвращаемого значения из шаблона Container

Добавлено через 1 минуту
C++
1
2
3
4
5
void Call(IArgument *arg, T* ret)
{
Arg_type* a = dynamic_cast< Arg_type* >(arg);
ret = (val1->*val2)(a->arg1, a->arg2, a->arg3);
}
Добавлено через 1 минуту
либо так:
C++
1
2
3
4
5
T Call(IArgument *arg)
{
Arg_type* a = dynamic_cast< Arg_type* >(arg);
return (val1->*val2)(a->arg1, a->arg2, a->arg3);
}
1
Egor138
32 / 13 / 2
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2
22.10.2013, 16:20  [ТС] #3
Raali, Это я пытался сделать. Но проблема что класс Delegate не знает об этом типе. К тому же фунция Call виртуально объявленна в классе IContainer, следовательно тип шаблона я туда вставить не могу. Вот и получаются ошибки. Подскажите как в таком случае все это организовать
0
Jupiter
Каратель
Эксперт С++
6564 / 3985 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
22.10.2013, 16:22 #4
Цитата Сообщение от Egor138 Посмотреть сообщение
Но проблема что класс Delegate не знает об этом типе. Подскажите как в таком случае написать operator()
так сделай чтоб знал
1
Raali
638 / 342 / 42
Регистрация: 06.07.2013
Сообщений: 1,107
Завершенные тесты: 1
22.10.2013, 16:23 #5
Цитата Сообщение от Egor138 Посмотреть сообщение
Но проблема что класс Delegate не знает об этом типе.
в таком случае всегда можно посылать любой параметр как void* ,
главное чтобы получатель знал какой тип ему нужен(что в принципе очевидно), тогда он сможет его интерпретировать как угодно
0
Egor138
32 / 13 / 2
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2
22.10.2013, 19:08  [ТС] #6
Цитата Сообщение от Jupiter Посмотреть сообщение
так сделай чтоб знал
Всмысле сделать?? Как ??
0
Jupiter
Каратель
Эксперт С++
6564 / 3985 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
22.10.2013, 19:12 #7
Цитата Сообщение от Egor138 Посмотреть сообщение
Всмысле сделать?? Как ??
так же как и класс контейнера сделан
0
Egor138
32 / 13 / 2
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2
22.10.2013, 19:23  [ТС] #8
Цитата Сообщение от Jupiter Посмотреть сообщение
так же как и класс контейнера сделан
Вы имеете ввиду частичную специализацию? Тогда как мне объявить все те операторы в пользовательском классе.

Тоесть мне нужно чтобы пользователь делал так

C++
1
Delegate d1;
А не так

C++
1
Delegate<тип, тип> d1;
Добавлено через 3 минуты
Raali, что то у меня не получается по вашему способу. Если есть указатель и я присваиваю ему локальную переменную, в данном случае возвращаемое значение функции, разве после работы программы значение просто не удалится??? Может нужно выделить память?

Вот

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
           class IContainer {public: virtual void Call(IArgument*, void*) {}};
 
    void operator ()()
    {
        void *ret;
        p_container->Call(&Argument<>(), ret);
    }
 
    void Call(IArgument *arg, Ret_Type *ret)
    {
        ret = new Ret_Type;
        *ret = (val1->*val2)();
        std::cout<<*ret;
    }
Что то не получается
0
Jupiter
Каратель
Эксперт С++
6564 / 3985 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
22.10.2013, 19:33 #9
Цитата Сообщение от Egor138 Посмотреть сообщение
Тоесть мне нужно чтобы пользователь делал так
Цитата Сообщение от Egor138 Посмотреть сообщение
А не так
на виртуальных методах как это сделано сейчас не получиться
0
Egor138
32 / 13 / 2
Регистрация: 10.08.2012
Сообщений: 619
Записей в блоге: 2
22.10.2013, 19:38  [ТС] #10
Цитата Сообщение от Jupiter Посмотреть сообщение
на виртуальных методах как это сделано сейчас не получиться
Я никак не могу понять, как тогда мне возвращать значение?? Или вообще не получится так как я хочу?
0
22.10.2013, 19:38
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.10.2013, 19:38
Привет! Вот еще темы с ответами:

Возвращаемое значение cos() - C++
Всем доброго времени суток. не могу понять почему cos() возвращает такие значения... cout&lt;&lt;&quot;F &quot;&lt;&lt;cos(90*M_PI/180.0)&lt;&lt;endl; ...

Возвращаемое значение функции - C++
void tokenize(string str_translate){ char char_translate; strcpy(char_translate, str_translate.c_str()); // string to char* ...

Возвращаемое значение функции - C++
array&amp; array::operator = (const array &amp;q) { if (this != &amp;q) { delete s; s=new int; for(len=0;len&lt;q.len;s=q.s,len++) ...

Возвращаемое значение функции - C++
Здарвствуйте. Моя задача состоит в написании следующей программы: вычислить среднее арифметическое значение элементов матрицы W(L,L),...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.