20 / 20 / 3
Регистрация: 01.04.2010
Сообщений: 57
|
||||||||||||||||
1 | ||||||||||||||||
CALLBACK. Нужна помощь06.11.2011, 21:52. Показов 2341. Ответов 28
Метки нет (Все метки)
Всем привет!
Есть такой код:
error C2064: результатом вычисления фрагмента не является функция, принимающая 4 аргументов подскажите, что не так?
0
|
06.11.2011, 21:52 | |
Ответы с готовыми решениями:
28
For_each и аргументы callback-функции; Как передать callback'у больше одного аргумента НУЖНА ПОМОЩЬ СРОЧНО НУЖНА ПОМОЩЬ! Нужна информация о тест оборудовании Нужна помощь |
Заблокирован
|
||||||
06.11.2011, 22:13 | 2 | |||||
- очень просто в прототип fn содержит отличное от 4-х число аргументов...
Добавлено через 1 минуту Не по теме: Вы наверное что то типа такого хотели сделать
0
|
20 / 20 / 3
Регистрация: 01.04.2010
Сообщений: 57
|
|||||||||||
06.11.2011, 22:20 [ТС] | 3 | ||||||||||
эмм, я наверно чего-то не понимаю..
я же в *.h файле описал
Просто где то в других методах я говорю что:
0
|
20 / 20 / 3
Регистрация: 01.04.2010
Сообщений: 57
|
|||||||||||
07.11.2011, 00:03 [ТС] | 6 | ||||||||||
спасибо, вот код:
0
|
20 / 20 / 3
Регистрация: 01.04.2010
Сообщений: 57
|
|
07.11.2011, 00:30 [ТС] | 8 |
вся прога большая. это отдельный класс. в методе main() просто создается экземпляр этого класса. код просто не компилируется
0
|
Заблокирован
|
|
07.11.2011, 00:39 | 9 |
Я понимаю, смысл в том, что бы я мог скопипастить, и скомпилить у себя. А потом уже разбираться, что не так.
Мне нужно знать точно, как класс предполагается использовать. И проще будит спросить у автора пример кода с использованием, чем самому догонять как должно работать нечто, что даже не компилируется. Поэтому, сделайте так: откройте отдельный мини-проектик. Перенесите в этот проектик только то, что относится к делу. Выложите сдесь. Будим тестировать и выяснять. Желательно, если код будут сопровождать комментарии (что бы было понятно сразу, что делают методы классов, и зачем эти классы вообще нужны)
1
|
20 / 20 / 3
Регистрация: 01.04.2010
Сообщений: 57
|
|
07.11.2011, 00:59 [ТС] | 10 |
Спасибо огромное!
Проэкт и задание в attach'e. Из задание (что в pdf) этот проэкт относится к 7му пункту (на 5й странице pdf'ки).
0
|
Заблокирован
|
|
07.11.2011, 01:23 | 11 |
atomohod , мне нужны три файла:
1. ExpressionCalculator.h //тестируемый класс 2. ExpressionCalculator.cpp //реализация класса 3. main.cpp //здесь не должно быть ничего лишнего. Только пример работы тестируемого класса, иллюстрирующий неполадку. Мне не нужен весь проект целиком. Мне не нужен main.cpp с километровой простыней кода. Мне не нужны студийные файлы, тем более, что у меня нет студии, с помощью которой я смог бы открыть солюшен. Мне нужны только три файла.
0
|
20 / 20 / 3
Регистрация: 01.04.2010
Сообщений: 57
|
|
07.11.2011, 01:35 [ТС] | 12 |
есть такое дело =)
0
|
Заблокирован
|
||||||
07.11.2011, 02:03 | 13 | |||||
atomohod, о том, какие роли выполняют классы, и что означают из методы аля f1(), f2() - это пусть каждый сам догадывается, да?
Ладно... итак...
0
|
20 / 20 / 3
Регистрация: 01.04.2010
Сообщений: 57
|
|
07.11.2011, 02:08 [ТС] | 14 |
f1() и f2() это функции, которые в 7 задании в пдф.
я хотел, получить значение функции, которая была вызвана последней для данного объекта, передав ей соответсвующие значения a, b, c, d. т.е. создав объект ExpressionCalculator и вызваз у него f1() например, указатель *f указывает на эту функцию, которая была вызвана, и потом, вызвав метод Calculate(...) я могу не зная то какая функция вызывалась последней, получить нужное значение. я только учусь, и возможно это можно сделать проще и логичней. В этом проекте я просто разбираюсь с callback
0
|
Заблокирован
|
|||||||||||||||||||||||||||||||
07.11.2011, 05:47 | 15 | ||||||||||||||||||||||||||||||
Честно говоря, я так и не понял, что за проблема такая. Мне самому интересно разобраться.
Я локализировал проблему:
дальнейший анализ проблемы: Этот код уже компилируется:
Ну вроде разобрался более менее. Сейчас буду заводить код Топик-Стартера. Должен будит хотя б скомпилироваться. Но подозреваю, что там помимо паленного синтаксиса есть ещё один серьёзный фейл Добавлено через 38 минут Обрати внимание, как я объявил указатель на метод класса. Я использовал typedef что бы улучшить читабельность кода
1. Идёт обращение к указателю, который указывает на метод класса 2. Запускается этот метод класса для объекта, на который указывает this 3. И результат работы этого метода записывается в переменную tmp Собака была зарыта в том, что не_статический метод класса не может быть запущен сам по себе. Он всегда запускается для какого то конкретного экземпляра класса. И нужно компилятору обязательно знать this объекта, для которого сработает метод, на который указывает указатель. Добавлено через 22 минуты точнеее... все немножко иначе... Когда мы хотим запустить не_статический метод класса, мы должны указатель компилятору для какого объекта мы его запускаем. Например: ptrObj -> Method(); Зная тип указателя, и зная, что указатель указывает на начало объекта, компилятор догадается какую именно функцию и для какого объекта нужно запустить. Указатель на метод класса содержит указатель на сам метод, но не знает, для какого именно из объектов этот метод нужно запустить. *ptrFunc(); // эта запись эквивалентна вызову Method(); для класса. Но компилятору нужно знать для какого объекта метод запускается! (ptrObj->*ptrFunc)(); //эквивалентна ptrObj -> Method(); Читать её нужно так: Для объекта, на который указывает ptrObj, запустить метод на который указывает ptrFunc, с аргументами, которые стоят в скобках. (в моём примере там ничего не стоит) Добавлено через 28 минут Можно ещё глубже проанализировать эту картинку: допустим мы хотим объявить указатель на обычную функцию:
Из примера видно, что запись (*test)(); Компилятор заменит на Foo(); То бишь, в качестве имени функции будит выступать значение указателя, а то что в скобочках так и останется Что происходит с указателем_на_метод класса? Абсолютно тоже самое! Вместо указателя_на_метод компилятор подставит имя реального метода, скормив ему те же самые аргументы. Проблема в том, что не_статический метод класса сам по себе вызвать нельзя. Компилятор должен знать для какого объекта он его вызывает. Поэтому в записи: (Объект.*Указатель)() компилятор сначала *Указатель подменит на реальное имя метода класса Получится (Объект.Метод)() Если же объект не указать - будит ошибка компиляции. Исходя из всего выше изложенного можно сделать удивительный вывод. Оказывается, запись: (Объект.Метод)(); работает!!! Этот код компилируется:
/зыы Уважаемые модераторы, ваш форум жосско глючит этой ночью. Вот, шоб вы знали. Добавлено через 19 минут Подозреваю, что результатом вычисления фрагмента является функция, принимающая 5 аргуметов! И этот пятый аргумент - это указатель this Интересно, а можно как нибудь его так подсунуть функции, прям в качестве аргумента этой функции? Сейчас попробую... Добавлено через 7 минут Нет... напрямую закатать this в сам аргумент функции не получилось. Фокус не прошёл. Компилятор на такое сразу нафег послал.
2
|
20 / 20 / 3
Регистрация: 01.04.2010
Сообщений: 57
|
|
07.11.2011, 11:17 [ТС] | 16 |
Bers, огромнейшее вам спасибо! Разобрался сам и новичкам скилап жесткий сделал! Такое объяснение было бы неплохо в FAQ по CALLBACK'ам записать!
0
|
5056 / 3116 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
||||||
07.11.2011, 11:40 | 17 | |||||
Bers, всё немного не так. В вашем тексте постоянно фигурирует "компилятор подменит xxx на реальное имя метода". Он такой ерундой заниматься вряд ли будет (если и будет, то только в целях оптимизации). Вот, скажем так, контрпример:
Вся же проблема была в том, что, действительно, вызывать метод через указатель надо специальным оператором ->* (для указателя на объект класса) или .* (для ссылки или самого объекта).
1
|
Заблокирован
|
|
07.11.2011, 18:08 | 18 |
silent_1991, понятно, что я утрирую для понимания именно с точки зрения высокоуровневого программиста, а не с точки зрения низко-уровневой механики.
Я сейчас объясню: Вот смотрите, допустим у нас есть объект, и есть указатель на этот объект. Тогда доступ к объекту через указатель делается так: ptr -> Method(); Или вот так: (*ptr).Method(); Во втором варианте в скобочках вычисляется выражение, а именно, "взятие значение по адресу" Вопрос: что такое "значение по адресу" ? Ответ на этот вопрос зависит от уровня программиста. Высокоуровневый программист, вроде меня скажет: Ответ: данные, чей тип совпадает с типом указателя, который на них указывает. Ну то есть вместо (*ptr) будит подставлен сам объект, который живет по адресу на который указывает ptr С указателями на функцию абсолютно аналогично. Понятно, что с точки зрения низкоуровневого программиста понятие "значение по адресу" может быть более точным, и менее абстрактным. Так например (хоть я и не знаю ассемблера), я догадываюсь, что на самом деле имя функции - это просто идентификатор. Тот же самый указатель, который указывает на адрес памяти, где находится исполняемый машинный код этой функции. А в записи: (obj.*ptrFunc)() на самом деле происходят два действия: 1. *ptrFunc высчитывает идентификатор функции (адрес её исполняемого кода) 2. Запуск этой функции, с передачей ей в качестве дополнительного аргумента this объекта Как то так. /зы На самом деле на высоком уровне такие нюансы реально знать не нужно. Если программист реально хочется поднять свой скилл, и во всем этом досканально разбираться, то ему нужно учить ассемблер, а не пытаться втиснуть в высокоуровневые рамки низкоуровневые абстракции, имхо.
0
|
5056 / 3116 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
07.11.2011, 21:44 | 19 |
Bers, с моей точки зрения, язык С++ немного отличается от других языков в этом плане. Сейчас объясню. Я, конечно, на 100 процентов не уверен, но, на мой взгляд, относительно куда меньше программистов на джаве или на шарпе относительно программистов на С++ знают механизм реализации, скажем, виртуальных функций. Они пишут на высоком уровне и им по барабану, что вообще существуют указатели, что также существуют ещё и указатели на функции, и что эти указатели можно собирать в таблицу и заставлять указывать на методы класса. У них есть виртуальные методы как данность, и они ей пользуются. И это, вообще говоря, замечательно. С++ же несколько иной. Хочешь-не хочешь, а он заставит тебя разобраться в этих деталях, если ты хоть немного хочешь понимать, что же там происходит. Мы в этой теме обсуждаем указатели на методы класса, так о каком таком высоком уровне может идти речь?
В общем, моё мнение такое: если браться объяснять кому-либо что-либо, то надо объяснять это корректно и в деталях, а не абстрактно и перевирая истину.
0
|
Заблокирован
|
||||||
07.11.2011, 22:13 | 20 | |||||
Хорошо. Я согласен с вами. но ответьте мне на такой вопрос:
в лексеме (*test) () что будит поставлено вместо *test ? На самом деле? Я предполагаю - идентификтор имени функции, который является ни чем иным, как указателем на начало блока памяти, в котором записаны исполняемые инструкции машины. Но если я прав, тогда в чем же я приверал? А если я не прав - объясните мне, в чем я не прав, что бы я знал.
0
|
07.11.2011, 22:13 | |
07.11.2011, 22:13 | |
Помогаю со студенческими работами здесь
20
Нужна помощь. Нужна Помощь Нужна помощь! Нужна помощь по ОУ Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |