А что, на функцию может быть не только указатель, но и ссылка?
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
-
- Сообщения: 1228
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
Стандарт стоит 60$
Но один из последних кандидатов в стандарты можно скачать бесплатно.
http://www.open-std.org/jtc1/sc22/wg21/ ... /n4296.pdf
Судя по этому документу, ссылки на функции стандартны (Пример можно найти в параграфе 8.5.3).
Но один из последних кандидатов в стандарты можно скачать бесплатно.
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" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
На самом деле особой разницы между ссылкой и указателем нет. Ссылка - это тот же указатель, только синтаксически выглядит несколько иначе и обладает более высоким уровнем безопасности по сравнению с обычным указателем. Применение ссылки подразумевает, что через неё будет передаваться адрес реально существующего экземпляра объекта, а не сырой указатель, который может быть никак не проинициализирован, даже нулём. В то время как ссылочную переменную без инициализации компилятор воспринимает за ошибку. А на бинарном уровне вообще разницы нет никакой - компилятор превращает ссылку в такой же адрес, что и обычный указатель.
Поумнеть несложно, куда труднее от дури избавиться.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Да, это всё понятно. Просто никогда не встречал синтаксиса даже такого для случая функций.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Не совсем так. Если ссылка - обычная переменная, то это просто синоним другого объекта и превращение в адрес может быть всзять на этапе компиляции, в отличие от указателя, значение которого читается на этапе исполнения и используется как адрес. Но если ссылка - параметр/операнд, то в неё заворачивается тот же указатель. И ни какой защиты на непроиниченную ссылку в этом случае нет, в такой параметр/операнд можно передать любой разыменованный указатель, в том числе, не проиниченный, в результате ссылка проиничена то будет, но мусором. Но память по ссылке в обоих случаях не может быть освобождена, а адрес сущности, на которую она ссылается, нельзя изменить. При этом в обоих случаях ссылка имеет синтаксис использования, совпадающий с синтаксисом обращения к самой сущности, не надо ни брать адрес сущности при передаче её в параметр, ни разыменовывать её в теле функции/оператора. Как вызывается std::endl? Передаётся прямо в оператор вывода без оператора взятия адреса. Но если оператор ожидает указатель, то такой синтаксис не доспустим. MinGW исправляет, автоматически подставляя взятие адреса. Но здесь некоторые утверждают, что такое поведение не стандартно и компилятор может заругаться. А если оператор принимает ссылку на функцию, то можно сразу передавать саму функцию, в том числе std::endl, без оператора взятия адреса и уже не имеет значения, подставляет ли компилятор оператор взятия адреса. Но зато важно, поддерживает ли компилятор ссылки на функции. Вот я и попробовал по намёку Ромео заменить в типе указателя на потоковый манипулятор * на &, MinGW это проглотил, а я засомневался, то ли я сделал.
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Я тоже как-то экспериментировал с указателями и ссылками в параметрах функций. Взял экспортируемую из DLL функцию, у которой входным параметром был указатель на некую структуру. Использовал динамическое связывание, т.е. LoadLibrary(), GetProcAddress() и т.д.
Когда полученный адрес функции приводил к её прототипу, то в самом прототипе функции заменил тип указателя на ссылку. И всё нормально у меня работало. Т.е. реализовать саму функцию в DLL можно как обычную для синтаксиса языка СИ (принимать данные через указатели), а использовать уже в стиле языка С++ (передавать параметры через ссылки).
Когда полученный адрес функции приводил к её прототипу, то в самом прототипе функции заменил тип указателя на ссылку. И всё нормально у меня работало. Т.е. реализовать саму функцию в DLL можно как обычную для синтаксиса языка СИ (принимать данные через указатели), а использовать уже в стиле языка С++ (передавать параметры через ссылки).
Каким компилятором?
Писать можно на чём угодно, но зачем же так себя ограничивать? Пиши на c.
Microsoft Visual C++ я использовал.
В настоящее время я использую версии VC++ от 2010, 2012 годов и новее, но подойдут и более старые версии.
В настоящее время я использую версии VC++ от 2010, 2012 годов и новее, но подойдут и более старые версии.
-
- Сообщения: 1228
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
Ну на самом деле даже Страуступ признавался что он уже не целиком знает язык.Забавно. Выходит просто никогда не пользовался ссылками на функции. Думал, что всё знаю уже по языку - 11 лет этим занимаюсь, всё-таки.
2B OR NOT(2B) = FF
-
- Сообщения: 1228
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
На этапе компиляции никаких адресов не существует. Если действительно нужно передать каллбэк безопасно это можно сделать при помощи шаблона если интерфейс класса не виртуальный и можно вынести все тело функции принимающей каллбэк в .h файл.Не совсем так. Если ссылка - обычная переменная, то это просто синоним другого объекта и превращение в адрес может быть всзять на этапе компиляции, в отличие от указателя, значение которого читается на этапе исполнения и используется как адрес
Код: Выделить всё
class Clazz {
...
template<typename Callable> void someMethod(Callable callback) {
///...
callback();
///...
}
//..
};
2B OR NOT(2B) = FF