А что, на функцию может быть не только указатель, но и ссылка?

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Стандарт стоит 60$

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

http://www.open-std.org/jtc1/sc22/wg21/ ... /n4296.pdf

Судя по этому документу, ссылки на функции стандартны (Пример можно найти в параграфе 8.5.3).
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Забавно. Выходит просто никогда не пользовался ссылками на функции. Думал, что всё знаю уже по языку - 11 лет этим занимаюсь, всё-таки. И на старуху бывает проруха, оказывается :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Decoder
Сообщения: 308
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

На самом деле особой разницы между ссылкой и указателем нет. Ссылка - это тот же указатель, только синтаксически выглядит несколько иначе и обладает более высоким уровнем безопасности по сравнению с обычным указателем. Применение ссылки подразумевает, что через неё будет передаваться адрес реально существующего экземпляра объекта, а не сырой указатель, который может быть никак не проинициализирован, даже нулём. В то время как ссылочную переменную без инициализации компилятор воспринимает за ошибку. А на бинарном уровне вообще разницы нет никакой - компилятор превращает ссылку в такой же адрес, что и обычный указатель.
Поумнеть несложно, куда труднее от дури избавиться.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Да, это всё понятно. Просто никогда не встречал синтаксиса даже такого для случая функций.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Не совсем так. Если ссылка - обычная переменная, то это просто синоним другого объекта и превращение в адрес может быть всзять на этапе компиляции, в отличие от указателя, значение которого читается на этапе исполнения и используется как адрес. Но если ссылка - параметр/операнд, то в неё заворачивается тот же указатель. И ни какой защиты на непроиниченную ссылку в этом случае нет, в такой параметр/операнд можно передать любой разыменованный указатель, в том числе, не проиниченный, в результате ссылка проиничена то будет, но мусором. Но память по ссылке в обоих случаях не может быть освобождена, а адрес сущности, на которую она ссылается, нельзя изменить. При этом в обоих случаях ссылка имеет синтаксис использования, совпадающий с синтаксисом обращения к самой сущности, не надо ни брать адрес сущности при передаче её в параметр, ни разыменовывать её в теле функции/оператора. Как вызывается std::endl? Передаётся прямо в оператор вывода без оператора взятия адреса. Но если оператор ожидает указатель, то такой синтаксис не доспустим. MinGW исправляет, автоматически подставляя взятие адреса. Но здесь некоторые утверждают, что такое поведение не стандартно и компилятор может заругаться. А если оператор принимает ссылку на функцию, то можно сразу передавать саму функцию, в том числе std::endl, без оператора взятия адреса и уже не имеет значения, подставляет ли компилятор оператор взятия адреса. Но зато важно, поддерживает ли компилятор ссылки на функции. Вот я и попробовал по намёку Ромео заменить в типе указателя на потоковый манипулятор * на &, MinGW это проглотил, а я засомневался, то ли я сделал.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Я тоже как-то экспериментировал с указателями и ссылками в параметрах функций. Взял экспортируемую из DLL функцию, у которой входным параметром был указатель на некую структуру. Использовал динамическое связывание, т.е. LoadLibrary(), GetProcAddress() и т.д.
Когда полученный адрес функции приводил к её прототипу, то в самом прототипе функции заменил тип указателя на ссылку. И всё нормально у меня работало. Т.е. реализовать саму функцию в DLL можно как обычную для синтаксиса языка СИ (принимать данные через указатели), а использовать уже в стиле языка С++ (передавать параметры через ссылки).
Аватара пользователя
Сионист
Сообщения: 1211
Зарегистрирован: 31 мар 2014, 06:18

Каким компилятором?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Microsoft Visual C++ я использовал.
В настоящее время я использую версии VC++ от 2010, 2012 годов и новее, но подойдут и более старые версии.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Забавно. Выходит просто никогда не пользовался ссылками на функции. Думал, что всё знаю уже по языку - 11 лет этим занимаюсь, всё-таки.
Ну на самом деле даже Страуступ признавался что он уже не целиком знает язык.
2B OR NOT(2B) = FF
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

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

Код: Выделить всё

class Clazz {
...
template<typename Callable> void someMethod(Callable callback) {
 ///...  
 callback();
 ///...  
}
//..
};
2B OR NOT(2B) = FF
Ответить