Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/22: Рейтинг темы: голосов - 22, средняя оценка - 4.55
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144

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

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

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

C++
1
2
long My_sqr(long aNumber);
double My_sqr(double aNumber);
Такое вообще возможно?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.06.2019, 18:54
Ответы с готовыми решениями:

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

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

Что не так с возвращаемым типом ?
package first; public abstract class Form implements Parametr{ double height=1.0; String Name_Form; Fuel Fuel_New; ...

20
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
26.06.2019, 19:06
Лучший ответ Сообщение было отмечено 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
Заблокирован
26.06.2019, 19:11
return aNumber*aNumber;
0
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144
26.06.2019, 20:03  [ТС]
_stanislav,
ага, это понял. Спасибо.

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

P.S.
В других языках, чтоб не ошибиться, есть специальная директива “Overload”; а в С++ какие правила?
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
26.06.2019, 20:14
Цитата Сообщение от Artem_Pv Посмотреть сообщение
какие просто случайно оказались одноименными
если оказались одноименными значит оказались перегруженными. в принципе одноименные функции с разным типом и количеством параметров это разные функции.

Добавлено через 3 минуты
Цитата Сообщение от Artem_Pv Посмотреть сообщение
В других языках, чтоб не ошибиться, есть специальная директива “Overload”; а в С++ какие правила?
в С++ есть ключевое слово override, для виртуальных методов класса, для функций специальных слов не знаю.
1
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144
26.06.2019, 20:19  [ТС]
Цитата Сообщение от _stanislav Посмотреть сообщение
если оказались одноименными значит оказались перегруженными
Пожалуйста, поясните.
Т.е. все одноименные функции из разных файлов считаются перегружаемыми?
Ведь это не серьезно..?
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
26.06.2019, 20:22
Цитата Сообщение от Artem_Pv Посмотреть сообщение
Т.е. все одноименные функции из разных файлов считаются перегружаемыми?
если у них разная сигнатура.

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

Добавлено через 24 секунды
и компилятор ошибку выдаст.
1
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144
26.06.2019, 20:31  [ТС]
Цитата Сообщение от _stanislav Посмотреть сообщение
если сигнатура одинаковая вступает в силу правило одного определения.
Например:
C++
1
2
3
4
5
6
// это моя функция, хочу использовать только ее
double My_sqr(double aNumber) {...} 
 
// и получается, что такой вызов опасный, 
// т.к. в другом файле может оказаться одноименная функция My_sqr(int aNumber)
My_sqr(2);
А как обезопаситься от "чужих" одноименных функций?
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
26.06.2019, 20:37
Цитата Сообщение от Artem_Pv Посмотреть сообщение
А как обезопаситься от "чужих" одноименных функций?
в пространства имен оборачиваться.

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

Добавлено через 3 минуты
но компилятор должен в принципе выдать сообщение о неоднозначном вызове, в этом конкретном случае.
1
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
26.06.2019, 20:38
Цитата Сообщение от Artem_Pv Посмотреть сообщение
А как обезопаситься от "чужих" одноименных функций?
Никак. В твоём случае - делай My_sqr(2.0). Но обычно такие функции вызываются не для констант, а для переменных. У них тип более определённый
1
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144
26.06.2019, 20:53  [ТС]
Цитата Сообщение от _stanislav Посмотреть сообщение
в пространства имен оборачиваться.
А как это на практике?
Предположим, обычная программа вызывает 100 функций, т.е. надо 100 раз указать пространство имен?

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

P.S.
спасибо за Ваше терпение.
0
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
26.06.2019, 21:04
Цитата Сообщение от Artem_Pv Посмотреть сообщение
В других языках программирования есть простая защита от “чужих” одноименных функций; Там можно не бояться, что одноименные “чужаки” будут вызваны только из-за того, что лучше совпала сигнатура.
Это где? И каким образом?

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

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

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

Добавлено через 5 минут
Цитата Сообщение от Artem_Pv Посмотреть сообщение
я НЕ переопределяю, а просто пишу свою функцию: void print(char *arg)
Если print(char *arg) именно с char * уже кем-то объявлена, создать свою ты уже не сможешь. Нужно будет либо создавать такую функцию внутри класса, либо внутри своей области видимости. И да, автоматическое приведение указателей на типы в С++ (так же как в С указателей на структуры) запрещено, так что вызвать print с указателем на тип double у тебя не получится.
1
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
26.06.2019, 21:34
Цитата Сообщение от Artem_Pv Посмотреть сообщение
и даже НЕ подозреваю, что может оказаться одноименный "чужак" , который без спросу влезет из-за совпавшей сигнатуры.
тут дело в том, что программист С++ всегда знает какие библиотеки у него подключены и какие имена могут в них быть.
опять же если не уверен, делай длинные названия, или всегда определяй свои функции в своем пространстве имен, либо у тебя всегда под рукой есть отладчик, который подскажет в какую функцию ты влез.
2
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
26.06.2019, 21:36
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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
26.06.2019, 23:30
Лучший ответ Сообщение было отмечено 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
1 / 1 / 0
Регистрация: 31.03.2019
Сообщений: 144
27.06.2019, 09:48  [ТС]
Спасибо всем, кто ответил.
Я понял, что нужно учиться дисциплине программирования в 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
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
27.06.2019, 09:58
Цитата Сообщение от Artem_Pv Посмотреть сообщение
А компилятор подскажет, что появились “опасные” одноименные функции?
Если имеет место быть неявное преобразование типа, Visual Studio 2019 показывает, что есть неоднозначный вызов функции, не знаю как на других платформах.
Если функции полностью идентичны, то любой компилятор это заметит и выдаст ошибку, если у функции одно имя но разные типы параметров (возвращаемый тип в счет не идет), компилятор посчитает ее перегруженной.

Добавлено через 57 секунд
Цитата Сообщение от Artem_Pv Посмотреть сообщение
"опасен" оператор with
что за оператор такой?
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.06.2019, 09:58
Помогаю со студенческими работами здесь

Событие с возвращаемым типом моего класса
Ситуация: У меня есть событие РАТ, оно типа делегата АТТ, который возвращает класс myclass, есть метод который подписан на событие. ...

Дочерний класс со своим методом и возвращаемым типом
Здравствуйте, е меня есть родитель, абстрактный класс, и производные классы, которые должны иметь один общий метод, но этот тетод будет...

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

[UWP] Возвращаемым типом асинхронного метода должен быть void, Task или Task<T>
Создал асинхронный метод. Он должен на выходе вывести объект который состоит из строк. Пишет ошибка, что можно сделать? Первый скрин с...

Функция с разным типом возвращаемых данных
Всем доброго времени суток! Нужно сделать некую библиотеку.В одной части библиотеки есть 3 разные структуры,возможно в дальнейшем их...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru