Страница 2 из 6

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

Добавлено: 07 дек 2015, 07:33
Absurd
Стандарт стоит 60$

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

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

Судя по этому документу, ссылки на функции стандартны (Пример можно найти в параграфе 8.5.3).

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

Добавлено: 07 дек 2015, 11:35
Romeo
Забавно. Выходит просто никогда не пользовался ссылками на функции. Думал, что всё знаю уже по языку - 11 лет этим занимаюсь, всё-таки. И на старуху бывает проруха, оказывается :)

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

Добавлено: 07 дек 2015, 11:39
Decoder
На самом деле особой разницы между ссылкой и указателем нет. Ссылка - это тот же указатель, только синтаксически выглядит несколько иначе и обладает более высоким уровнем безопасности по сравнению с обычным указателем. Применение ссылки подразумевает, что через неё будет передаваться адрес реально существующего экземпляра объекта, а не сырой указатель, который может быть никак не проинициализирован, даже нулём. В то время как ссылочную переменную без инициализации компилятор воспринимает за ошибку. А на бинарном уровне вообще разницы нет никакой - компилятор превращает ссылку в такой же адрес, что и обычный указатель.

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

Добавлено: 07 дек 2015, 11:59
Romeo
Да, это всё понятно. Просто никогда не встречал синтаксиса даже такого для случая функций.

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

Добавлено: 07 дек 2015, 12:38
Сионист
Не совсем так. Если ссылка - обычная переменная, то это просто синоним другого объекта и превращение в адрес может быть всзять на этапе компиляции, в отличие от указателя, значение которого читается на этапе исполнения и используется как адрес. Но если ссылка - параметр/операнд, то в неё заворачивается тот же указатель. И ни какой защиты на непроиниченную ссылку в этом случае нет, в такой параметр/операнд можно передать любой разыменованный указатель, в том числе, не проиниченный, в результате ссылка проиничена то будет, но мусором. Но память по ссылке в обоих случаях не может быть освобождена, а адрес сущности, на которую она ссылается, нельзя изменить. При этом в обоих случаях ссылка имеет синтаксис использования, совпадающий с синтаксисом обращения к самой сущности, не надо ни брать адрес сущности при передаче её в параметр, ни разыменовывать её в теле функции/оператора. Как вызывается std::endl? Передаётся прямо в оператор вывода без оператора взятия адреса. Но если оператор ожидает указатель, то такой синтаксис не доспустим. MinGW исправляет, автоматически подставляя взятие адреса. Но здесь некоторые утверждают, что такое поведение не стандартно и компилятор может заругаться. А если оператор принимает ссылку на функцию, то можно сразу передавать саму функцию, в том числе std::endl, без оператора взятия адреса и уже не имеет значения, подставляет ли компилятор оператор взятия адреса. Но зато важно, поддерживает ли компилятор ссылки на функции. Вот я и попробовал по намёку Ромео заменить в типе указателя на потоковый манипулятор * на &, MinGW это проглотил, а я засомневался, то ли я сделал.

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

Добавлено: 07 дек 2015, 13:06
WinMain
Я тоже как-то экспериментировал с указателями и ссылками в параметрах функций. Взял экспортируемую из DLL функцию, у которой входным параметром был указатель на некую структуру. Использовал динамическое связывание, т.е. LoadLibrary(), GetProcAddress() и т.д.
Когда полученный адрес функции приводил к её прототипу, то в самом прототипе функции заменил тип указателя на ссылку. И всё нормально у меня работало. Т.е. реализовать саму функцию в DLL можно как обычную для синтаксиса языка СИ (принимать данные через указатели), а использовать уже в стиле языка С++ (передавать параметры через ссылки).

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

Добавлено: 07 дек 2015, 14:56
Сионист
Каким компилятором?

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

Добавлено: 07 дек 2015, 15:24
WinMain
Microsoft Visual C++ я использовал.
В настоящее время я использую версии VC++ от 2010, 2012 годов и новее, но подойдут и более старые версии.

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

Добавлено: 07 дек 2015, 15:34
Absurd
Забавно. Выходит просто никогда не пользовался ссылками на функции. Думал, что всё знаю уже по языку - 11 лет этим занимаюсь, всё-таки.
Ну на самом деле даже Страуступ признавался что он уже не целиком знает язык.

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

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

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

class Clazz {
...
template<typename Callable> void someMethod(Callable callback) {
 ///...  
 callback();
 ///...  
}
//..
};