|
Функция, выполняющая действия с аргументами разных типов, Как сделать перегрузку функции |
|
|
|
 |
Ответов
(1 - 13)
|
Jun 14 2007, 21:02
|

山伏
    
Группа: Свой
Сообщений: 1 827
Регистрация: 3-08-06
Из: Kyyiv
Пользователь №: 19 294

|
Цитата(alux @ Jun 14 2007, 23:18)  Т.е. чтобы в функцию передавался аргумент, который может быть как unsigned char , так и signed char. Сейчас у меня работает так:: //Глобальные переменные unsigned char* ptr; unsigned char val; signed char offset; void valcodr(void);
//Определение void valcoder(void) { выполняет действия с ptr; }
//Вызов функции, которая изменяет переменную val ptr=&val; valcoder();
Вопрос. Как теперь заставить функцию работать с знаковой переменной offset? Возможна ли такая перегрузка функции? Хоть убейте, я вообще не понимаю, что Вы спрашиваете  , но может быть это спасет отца русской демократии  ? Цитата //Глобальные переменные unsigned char* ptr1; signed char* ptr2; unsigned char val; signed char offset; void valcodr( void); //Определение void valcoder( void) { //безобразничает с ptr1 и ptr2; } //Вызов функции, которая изменяет переменные val и offset вместе взятые ptr1 = &val; ptr1 = &offset; valcoder(); У Вас же функция работает c глобальными указателями на глобальные переменные. Ничего ей не передаеЦЦо и ничего она не возвращает. Хоть три (  ) переменных сразу обрабатуйте. Не очень элегантно, но когда человек покупает стиральную машину ему главное чтобы она долго и упорно работала, а не стиль зашитого в нее кода...  А чо функция так называеЦЦо? Валкодер крутите?
--------------------
Нас помнят пока мы мешаем другим... //-------------------------------------------------------- Хороший блатной - мертвый... //-------------------------------------------------------- Нет старик, это те дроиды которых я ищу...
|
|
|
|
|
Jun 15 2007, 06:50
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(KRS @ Jun 14 2007, 23:50)  Так у вас сейчас вообще у функции аргументов нет! Все через глобальные переменные. Причем ptr - указатель на беззнаковый тип. и адрес переменной offset ему будет присваивать не корректно. Очень ценное замечание... Я и не говорил, что сейчас в моей функции что-либо передавалось. Я спрашивал КАК сделать, чтобы функция могла работать с переменными разных типов. Возможно, это можно сделать через перегрузку функции. Как вы могли заметить, функция действительно называется valcoder. И по идее она должна изменять значение переменных, на которые указывает глобальный указатель. По крайней мере сейчас у меня так работает, только для переменных беззнакового типа. В общем я подумал, проще будет написать отдельную функцию для работы с знаковыми переменными. И соответственно создать указатель знакового типа. Или будут другие предложения?
Сообщение отредактировал alux - Jun 15 2007, 07:16
|
|
|
|
|
Jun 15 2007, 07:22
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(alux @ Jun 15 2007, 13:50)  Очень ценное замечание... Я и не говорил, что сейчас в моей функции что-либо передавалось. Я спрашивал КАК сделать, чтобы функция могла работать с переменными разных типов. Возможно, это можно сделать через перегрузку функции. Все-таки не понятно, что именно Вы хотите. Перегрузка имени функции - это использование одного имени для разных фукнций. Т.е. это не одна функция, которая работает с разныими данными, а это разные функции, которые работают с разными данными. Например: Код void f(int x) { ... } void f(float x) { ... }
...
f(1); // вызывается void f(int x) f(1.0) // вызывается void f(float x) Вообще, написать функцию, которая бы работала с разными типами данных на С++, нельзя - как компилятор будет знать, какой код ему родить, если он не знает их типов (ни размеров, ни форматов). Существует случай, когда хотя данные и разные, но работа с ними делается единообразно, и писать аналогичный, почти повторяющийся код в разных функциях не есть достойное занятие. Для этого случая в С++ имеются шаблоны, которые позволяют описать действия функции без привязки к конкретному типу, а при использовании - инстанцировать функцию по шаблону с заданным параметром. Например: Код template<typename T> T square(T x) { return x*x; }
...
int x = square(5);
printf("Result: %d\n", x);
float y = square(5.0);
printf("Result: %f\n", y);
результат:
Result: 25 Result: 25.000000 В общем, Вам бы надо поконкретнее определиться, что именно Вам нужно, и уже на основе этого выбирать средство для реализации.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jun 15 2007, 08:33
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(dxp @ Jun 15 2007, 10:22)  Существует случай, когда хотя данные и разные, но работа с ними делается единообразно, и писать аналогичный, почти повторяющийся код в разных функциях не есть достойное занятие. Для этого случая в С++ имеются шаблоны, которые позволяют описать действия функции без привязки к конкретному типу, а при использовании - инстанцировать функцию по шаблону с заданным параметром. Вот это уже ближе к делу. А есть ли такая возможность (создание шаблонов) в Си? Цитата(DRUID3 @ Jun 15 2007, 00:02)  Не очень элегантно, но когда человек покупает стиральную машину ему главное чтобы она долго и упорно работала, а не стиль зашитого в нее кода...  Согласен. Некрасиво работать через указатель на глобальные переменные. Сделал так: unsigned char value1; signed char value2; unsigned char valcoder(unsigned char); unsigned char valcoder(unsigned char x) { if(++x>250) x=0; ................ } //Вызов функции: value1=valcoder(value1); Для переменной signed char value2 функция valcoder должна сделать то же самое, отличие состоит только в проверке на другой диапазон. Если создать шаблонную функцию, как говорил dxp, можно ли создать специализированную версию функции? Например вот так: template <typename T> signed char valcoder(T x) { if(++x>120) x=0; .............. } //Вызов функции: value2=valcoder(value2);
Сообщение отредактировал alux - Jun 15 2007, 08:47
|
|
|
|
|
Jun 15 2007, 20:13
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(alux @ Jun 15 2007, 12:45)  Номер с template не прошел. Проще действительно создать раздельные функции для для разных типов переменных. Я конечно не знаю, какие магические действия делает ваша функция с глобальной переменной с помощью глобального указателя. То, что эти глобальные переменные никоим образом не являются аргументами функции вам уже объяснили. Но может вам подойдет такой вариант: Код signed char Valcoder() // не более +-127 пупок за раз {
} signed char Offset; unsigned char Val1; unsigned int Val2; signed long Val3;
void Test() { Offset += Valcoder(); if(Offset > 100) Offset = 100; else if(Offset < -100) Offset = -100; Val1 += Valcoder(); if(Val1 > 200) Val = 0; Val2 += Valcoder(); Val3 += Valcoder(); } или такой вариант, используя действительно параметры функции: Код signed int Valcoder(signed int init, signed int min, signed int max) { signed int Value = init; ........... if(Value < min) Value = min; if(Value > max) Value = max; .......... return Value;
} signed char Offset; unsigned char Val1; unsigned int Val2;
void Test() { Offset = Valcoder(Offset, -100, 100); Val1 = Valcoder(Val1, 0, 200); Val2 = Valcoder(Val2, 0, 65535); } Цитата(alux @ Jun 15 2007, 12:45)  Номер с template не прошел. Если вы пытались использовать их в С, то вас предупреждали - С не знает о template, только С++. Если у вас "номер не прошел" в С++, значит вы просто не смогли правильно объяснить компилятору, чего вы от него хотите.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 16 2007, 20:32
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(Сергей Борщ @ Jun 15 2007, 23:13)  Но может вам подойдет такой вариант: Код signed char Valcoder() // не более +-127 пупок за раз { } signed char Offset; unsigned char Val1; unsigned int Val2; signed long Val3;
void Test() { Offset += Valcoder(); if(Offset > 100) Offset = 100; else if(Offset < -100) Offset = -100; Val1 += Valcoder(); if(Val1 > 200) Val = 0; Val2 += Valcoder(); Val3 += Valcoder(); } или такой вариант, используя действительно параметры функции: Код signed int Valcoder(signed int init, signed int min, signed int max) { signed int Value = init; ........... if(Value < min) Value = min; if(Value > max) Value = max; .......... return Value;
} signed char Offset; unsigned char Val1; unsigned int Val2;
void Test() { Offset = Valcoder(Offset, -100, 100); Val1 = Valcoder(Val1, 0, 200); Val2 = Valcoder(Val2, 0, 65535); } Если вы пытались использовать их в С, то вас предупреждали - С не знает о template, только С++. Если у вас "номер не прошел" в С++, значит вы просто не смогли правильно объяснить компилятору, чего вы от него хотите. "Универсальность" функции - не всегда выгодна. Ваш первый вариант больше на 55 байт, чем вариант з раздельными функциями (для signed и unsigned char). Второй вариант не проверял, но он мне не совсем подходит. Но все-равно спасибо. Странно, что я до Вашего (1-го) варианта сразу не додумался.
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|