Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/12: Рейтинг темы: голосов - 12, средняя оценка - 5.00
Artem_Pv
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 130
Завершенные тесты: 1
1

Как перегружать функции с разным возвращаемым типом?

26.06.2019, 18:54. Просмотров 2152. Ответов 20
Метки нет (Все метки)

Не могу найти в Help-е, как это сделать.
Например, мне нужно перегрузить функции возведения в квадрат:

C++
1
2
long My_sqr(long aNumber);
double My_sqr(double aNumber);
Такое вообще возможно?
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.06.2019, 18:54
Ответы с готовыми решениями:

Шаблон функции с разным возвращаемым типом
Доброго времени суток! Возникла необходимость написать шаблон функции, которая будет возвращать...

независимо управлять типом входных данных массива для определения сред. ариф. и возвращаемым значением функции
Нужно сделать чтобы можно было независимо управлять типом входных данных массива для определения...

Как сделать вектор/массив объектов одного класса с разным <типом>
У меня есть класс MySet&lt;T&gt;, я хочу сделать массив/вектор таких объектов, в который можно будет...

Ошибка "перегруженная функция отличается от "Competitor uploadFromBinFile(int &)" только возвращаемым типом"
Пользовался Visual Studio Community 2017. //_______________ //|Header Files |...

В чем разница между типом функции и типом возвращаемого значения?
Читаю статью https:// code-live. ru/post/cpp-functions/ (ссылку изменил дабы не делать рекламу) ...

20
_stanislav
(80 / 20 || 50 / 50) = x
1193 / 923 / 354
Регистрация: 16.08.2014
Сообщений: 3,714
Записей в блоге: 1
Завершенные тесты: 2
26.06.2019, 19:06 2
Лучший ответ Сообщение было отмечено Artem_Pv как решение

Решение

Цитата Сообщение от Artem_Pv Посмотреть сообщение
Такое вообще возможно?
возможно, но перегрузка будет только для параметров работать. в смысле возвращаемые типы не обернуться в расчет при перегрузке.

Добавлено через 4 минуты
C++
1
2
3
4
5
6
7
8
9
10
long My_sqr(long aNumber) {return aNumber;}
double My_sqr(double aNumber) {return aNumber;}
 
int main()
{
    double d = My_sqr( (long)1); // Вызывается первый вриант
    long l = My_sqr( (double)2); // Вызывается второй вриант
 
    return 0;
}
Добавлено через 3 минуты
возвращаемый тип не явно кастится стандартными правилами преобразования типа.
1
Pvt
352 / 222 / 117
Регистрация: 25.06.2019
Сообщений: 813
26.06.2019, 19:11 3
return aNumber*aNumber;
0
Artem_Pv
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 130
Завершенные тесты: 1
26.06.2019, 20:03  [ТС] 4
_stanislav,
ага, это понял. Спасибо.

Еще вопрос про перегрузку:
Если в разных файлах есть функции с одинаковыми именами, то как компилятор определяет, какие из этих функций считать перегружаемыми, а какие просто случайно оказались одноименными(не планировались для перегрузки)?

P.S.
В других языках, чтоб не ошибиться, есть специальная директива “Overload”; а в С++ какие правила?
0
_stanislav
(80 / 20 || 50 / 50) = x
1193 / 923 / 354
Регистрация: 16.08.2014
Сообщений: 3,714
Записей в блоге: 1
Завершенные тесты: 2
26.06.2019, 20:14 5
Цитата Сообщение от Artem_Pv Посмотреть сообщение
какие просто случайно оказались одноименными
если оказались одноименными значит оказались перегруженными. в принципе одноименные функции с разным типом и количеством параметров это разные функции.

Добавлено через 3 минуты
Цитата Сообщение от Artem_Pv Посмотреть сообщение
В других языках, чтоб не ошибиться, есть специальная директива “Overload”; а в С++ какие правила?
в С++ есть ключевое слово override, для виртуальных методов класса, для функций специальных слов не знаю.
1
Artem_Pv
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 130
Завершенные тесты: 1
26.06.2019, 20:19  [ТС] 6
Цитата Сообщение от _stanislav Посмотреть сообщение
если оказались одноименными значит оказались перегруженными
Пожалуйста, поясните.
Т.е. все одноименные функции из разных файлов считаются перегружаемыми?
Ведь это не серьезно..?
0
_stanislav
(80 / 20 || 50 / 50) = x
1193 / 923 / 354
Регистрация: 16.08.2014
Сообщений: 3,714
Записей в блоге: 1
Завершенные тесты: 2
26.06.2019, 20:22 7
Цитата Сообщение от Artem_Pv Посмотреть сообщение
Т.е. все одноименные функции из разных файлов считаются перегружаемыми?
если у них разная сигнатура.

Добавлено через 30 секунд
если сигнатура одинаковая вступает в силу правило одного определения.

Добавлено через 24 секунды
и компилятор ошибку выдаст.
1
Artem_Pv
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 130
Завершенные тесты: 1
26.06.2019, 20:31  [ТС] 8
Цитата Сообщение от _stanislav Посмотреть сообщение
если сигнатура одинаковая вступает в силу правило одного определения.
Например:
C++
1
2
3
4
5
6
// это моя функция, хочу использовать только ее
double My_sqr(double aNumber) {...} 
 
// и получается, что такой вызов опасный, 
// т.к. в другом файле может оказаться одноименная функция My_sqr(int aNumber)
My_sqr(2);
А как обезопаситься от "чужих" одноименных функций?
0
_stanislav
(80 / 20 || 50 / 50) = x
1193 / 923 / 354
Регистрация: 16.08.2014
Сообщений: 3,714
Записей в блоге: 1
Завершенные тесты: 2
26.06.2019, 20:37 9
Цитата Сообщение от Artem_Pv Посмотреть сообщение
А как обезопаситься от "чужих" одноименных функций?
в пространства имен оборачиваться.

Добавлено через 1 минуту
Цитата Сообщение от Artem_Pv Посмотреть сообщение
// и получается, что такой вызов опасный,
// т.к. в другом файле может оказаться одноименная функция My_sqr(int aNumber)
получается так.

Добавлено через 3 минуты
но компилятор должен в принципе выдать сообщение о неоднозначном вызове, в этом конкретном случае.
1
oleg-m1973
1922 / 1339 / 541
Регистрация: 07.05.2019
Сообщений: 4,308
Записей в блоге: 1
26.06.2019, 20:38 10
Цитата Сообщение от Artem_Pv Посмотреть сообщение
А как обезопаситься от "чужих" одноименных функций?
Никак. В твоём случае - делай My_sqr(2.0). Но обычно такие функции вызываются не для констант, а для переменных. У них тип более определённый
1
Artem_Pv
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 130
Завершенные тесты: 1
26.06.2019, 20:53  [ТС] 11
Цитата Сообщение от _stanislav Посмотреть сообщение
в пространства имен оборачиваться.
А как это на практике?
Предположим, обычная программа вызывает 100 функций, т.е. надо 100 раз указать пространство имен?

Извиняюсь, за глупые вопросы(я 100% новичок в С++)
В других языках программирования есть простая защита от “чужих” одноименных функций; Там можно не бояться, что одноименные “чужаки” будут вызваны только из-за того, что лучше совпала сигнатура.
А в языке С++ есть простая защита от одноименных “чужаков” ?

P.S.
спасибо за Ваше терпение.
0
oleg-m1973
1922 / 1339 / 541
Регистрация: 07.05.2019
Сообщений: 4,308
Записей в блоге: 1
26.06.2019, 21:04 12
Цитата Сообщение от Artem_Pv Посмотреть сообщение
В других языках программирования есть простая защита от “чужих” одноименных функций; Там можно не бояться, что одноименные “чужаки” будут вызваны только из-за того, что лучше совпала сигнатура.
Это где? И каким образом?

Добавлено через 8 минут
Цитата Сообщение от Artem_Pv Посмотреть сообщение
А в языке С++ есть простая защита от одноименных “чужаков” ?
Единственная защита - предупреждения (если повезёт - ошибки) компилятора. Поэтому нужно внимательно относится к тому, как ты переопределяешь функции и методы.
Пространства имён - это не о том, это как делать функции с разными именами. Но это уже не переопределение, тупо другая функция, которую надо вызывать явно.
1
TRam_
зомбяк
1349 / 1024 / 297
Регистрация: 14.05.2017
Сообщений: 3,364
26.06.2019, 21:24 13
Цитата Сообщение от Artem_Pv Посмотреть сообщение
Там можно не бояться, что одноименные “чужаки” будут вызваны только из-за того, что лучше совпала сигнатура.
В данном конкретном случае и Java, и C# будут работать аналогично. Выбор сигнатуры функции будет в зависимости от типа аргумента (т.е. 2, 2.0, 2.0f, 2L - могут дать перебор 4 разных функций)
0
Artem_Pv
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 130
Завершенные тесты: 1
26.06.2019, 21:25  [ТС] 14
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
В твоём случае - делай My_sqr(2.0)
Например, в программе используются 100 функций, а т.к. программисту не известно, сколько одноименных "функций-чужков", у которых лучше подошла сигнатура, поэтому он должен для всех 100 функций следить, чтоб параметры были “2.0 вместо 2” ... ?
Это ведь несерьезно /

В других языках, одноименные функции не являются угрозой, т.к. совпадение имени еще недостаточно, чтоб быть перегруженной, требуется спец.директива "overload".
Подозреваю, что в С++ тоже присутствует защита... просто надо ее отыскать.

Цитата Сообщение от oleg-m1973 Посмотреть сообщение
нужно внимательно относится к тому, как ты переопределяешь
В том то и дело, я НЕ переопределяю, а просто пишу свою функцию: void print(char *arg);
и даже НЕ подозреваю, что может оказаться одноименный "чужак" , который без спросу влезет из-за совпавшей сигнатуры.
0
TRam_
зомбяк
1349 / 1024 / 297
Регистрация: 14.05.2017
Сообщений: 3,364
26.06.2019, 21:33 15
Цитата Сообщение от Artem_Pv Посмотреть сообщение
простая защита от одноименных “чужаков”
Не плодить одноимённые функции, если не уверен что "случайно появившееся" преобразование типа сломает логику твоего кода.

Добавлено через 5 минут
Цитата Сообщение от Artem_Pv Посмотреть сообщение
я НЕ переопределяю, а просто пишу свою функцию: void print(char *arg)
Если print(char *arg) именно с char * уже кем-то объявлена, создать свою ты уже не сможешь. Нужно будет либо создавать такую функцию внутри класса, либо внутри своей области видимости. И да, автоматическое приведение указателей на типы в С++ (так же как в С указателей на структуры) запрещено, так что вызвать print с указателем на тип double у тебя не получится.
1
_stanislav
(80 / 20 || 50 / 50) = x
1193 / 923 / 354
Регистрация: 16.08.2014
Сообщений: 3,714
Записей в блоге: 1
Завершенные тесты: 2
26.06.2019, 21:34 16
Цитата Сообщение от Artem_Pv Посмотреть сообщение
и даже НЕ подозреваю, что может оказаться одноименный "чужак" , который без спросу влезет из-за совпавшей сигнатуры.
тут дело в том, что программист С++ всегда знает какие библиотеки у него подключены и какие имена могут в них быть.
опять же если не уверен, делай длинные названия, или всегда определяй свои функции в своем пространстве имен, либо у тебя всегда под рукой есть отладчик, который подскажет в какую функцию ты влез.
2
zayats80888
2276 / 1353 / 560
Регистрация: 07.02.2019
Сообщений: 3,608
26.06.2019, 21:36 17
Artem_Pv,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace My
{
    void print(const char*) {}
    double sqrt(double) {}
    //...
}
 
int main()
{
    //...
    My::print("asdasd");
    //...
    std::cout << My::sqrt(123);
    //...
}
1
DrOffset
11614 / 6302 / 1518
Регистрация: 30.01.2014
Сообщений: 10,257
26.06.2019, 23:30 18
Лучший ответ Сообщение было отмечено Artem_Pv как решение

Решение

Artem_Pv, откровенно говоря, эта проблема действительно существует и редко, очень редко, но бывает, что портит много крови, особенно в огромных проектах.
Какой-то языковой защиты от этого нет, потому что это фича, а не баг.
Пространства имен могут помочь, желательно следить за уникальностью имен с помощью них, или других средств, но не всегда это спасает. Например вот в такой ситуации то, что ваша функция находится в пространстве имен, не спасет:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void foo(int); // чужая функция где в глубине библиотечных заголовочных файлов
 
// территория вашего проекта
namespace your_project
{
 
void foo(double); 
 
//....
 
void bar()
{
    foo(1); // помогло бы your_project::foo(1);
}
 
} // namespace your_project
В этом случае все равно вызовется "неправильная" функция, не смотря на то, что ваша объявлена в namespace.
К сожалению не все разработчики сознательные и поставляют свои библиотеки с заботой об уникальности имен. И тогда могут возникнуть подобные неприятные ситуации.

Поэтому заботиться об этом нужно в первую очередь дисциплиной:

\ Если вы хотите вызывать функцию именно из глобального пространства имен - пишите перед ней ::. Это поможет не спутать ее с одноименными в ваших классах или неймспейсах.
\ Если у вас подозрение, что имя неуникально, то лучше позаботиться явном указании типов (как вам советовали выше), или явном указании пространства имен, где эта функция находится.
\ И вообще, неявные преобразования опасны. Для того, чтобы исключить неявные преобразования есть набор инструментов, как языковых (explicit, brace initialization), так и стилистических (рекомендация не злоупотреблять пользовательскими операторами преобразования).
\ Сюда же относится непонимаемый многими новичками практический запрет на использование using namespace std; именно затем он и запрещен, чтобы не плодить неуникальные сущности искусственно. В общем-то это справедливо не только для std, но и любого другого namespace.
___

На самом деле, даже если бы в С++ был явный механизм управления перегрузками, это не защитило бы от подобных ошибок. Допустим два независимых разработчка написали функцию print. У каждого из них по 2 перегрузки этой функции. Один написал их для char и int, другой для short и long. Естественно каждый разработчик пометил свои функции как перегруженные. Затем все четыре функции попали каким-то образом в один проект и программист этого проекта опять наткнулся на неочевидное поведение. Ничего не изменилось, хотя, казалось бы, все сделано правильно.
___

И все-таки, я хотел бы вас успокоить: за многолетнюю практику лично я встречался с таким о силы раза 3. Действительно тогда пришлось попотеть, чтобы понять в чем причина.
Если же придерживаться рекомендаций по написанию программ, то шанс подобного сводится к очень маленькой вероятности. Со временем перестаешь обращать на это внимание, и <правильно> получается уже на автомате.
2
Artem_Pv
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 130
Завершенные тесты: 1
27.06.2019, 09:48  [ТС] 19
Спасибо всем, кто ответил.
Я понял, что нужно учиться дисциплине программирования в C++
для меня это пока новый непонятный мир.
Вот мой пример:
C++
1
2
3
4
5
6
// это моя функция, хочу использовать только ее! 
My_Calc(double aDouble) {...} 
 
// но, получается, что такой вызов опасный: 
My_Calc(2);
// т.к. в другом файле через год, два,... может оказаться одноименная функция My_Calc(long aLong)
К сожалению, я не способен следить за одноименными “чужаками”, которые могут появиться спустя длительное время.
Последняя надежда на автоматику.

Отсюда Вопрос:
А компилятор подскажет, что появились “опасные” одноименные функции?

Добавлено через 8 минут
P.S.
даже боюсь представить, насколько в C++ д.б. "опасен" оператор with ... ?!
А в других языках, оператор with не считается опасным.
0
_stanislav
(80 / 20 || 50 / 50) = x
1193 / 923 / 354
Регистрация: 16.08.2014
Сообщений: 3,714
Записей в блоге: 1
Завершенные тесты: 2
27.06.2019, 09:58 20
Цитата Сообщение от Artem_Pv Посмотреть сообщение
А компилятор подскажет, что появились “опасные” одноименные функции?
Если имеет место быть неявное преобразование типа, Visual Studio 2019 показывает, что есть неоднозначный вызов функции, не знаю как на других платформах.
Если функции полностью идентичны, то любой компилятор это заметит и выдаст ошибку, если у функции одно имя но разные типы параметров (возвращаемый тип в счет не идет), компилятор посчитает ее перегруженной.

Добавлено через 57 секунд
Цитата Сообщение от Artem_Pv Посмотреть сообщение
"опасен" оператор with
что за оператор такой?
1
27.06.2019, 09:58
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.06.2019, 09:58

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Вычисление кубического корня с использованием функции с параметрами и возвращаемым значением
Составьте программу для вычисления кубического корня из произвольного числа arg, вводимого...

Как искать функции, работающие с определенным типом?
Всем привет! Сейчас у меня типичная нудная задача: создать строку wchar_t, конвертировать цифру...

Объявить прототип функции f1 с 2 аргументами-строками и возвращаемым результатом в виде литерного массива
Здрасте всем), есть такая задачка: Объявить прототип функции f1 с 2 аргументами-строками и...


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

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

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