Форум программистов, компьютерный форум CyberForum.ru

CALLBACK. Нужна помощь - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.78
atomohod
 Аватар для atomohod
20 / 20 / 1
Регистрация: 01.04.2010
Сообщений: 57
06.11.2011, 21:52     CALLBACK. Нужна помощь #1
Всем привет!

Есть такой код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class ExpressionCalculator
{
private:
    double(ExpressionCalculator::*fn)(double,double,double,double);
public:
    ExpressionCalculator(void);
    ~ExpressionCalculator(void);
 
    double f1(double a, double b, double c, double d);
    double f2(double a, double b, double c, double d);
    double f3(double a, double b, double c, double d);
 
    double Calculate(double a, double b, double c, double d);
 
};
в *.cpp пробую:
C++
1
2
3
4
5
double ExpressionCalculator::Calculate(double a, double b, double c, double d)
{
    double tmp = fn(a,b,c,d);
    return tmp;
}
на
C++
1
double tmp = fn(a,b,c,d);
получаю при компиляции

error C2064: результатом вычисления фрагмента не является функция, принимающая 4 аргументов

подскажите, что не так?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.11.2011, 21:52     CALLBACK. Нужна помощь
Посмотрите здесь:

C++ НУЖНА ПОМОЩЬ В С++
C++ Нужна помощь.
C++ Нужна помощь
Нужна помощь C++
C++ Нужна помощь
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
Заблокирован
Автор FAQ
06.11.2011, 22:13     CALLBACK. Нужна помощь #2
Цитата Сообщение от atomohod Посмотреть сообщение
fn(a,b,c,d);
- очень просто в прототип fn содержит отличное от 4-х число аргументов...

Добавлено через 1 минуту

Не по теме:

Вы наверное что то типа такого хотели сделать

C++
1
2
for(n = 1; n < 3; n++)
   tmp = fn(a,b,c,d);
- просто другой ошибки в голову не пришло

atomohod
 Аватар для atomohod
20 / 20 / 1
Регистрация: 01.04.2010
Сообщений: 57
06.11.2011, 22:20  [ТС]     CALLBACK. Нужна помощь #3
эмм, я наверно чего-то не понимаю..
я же в *.h файле описал

C++
1
double(ExpressionCalculator::*fn)(double,double,double,double);
Я же правильно понимаю что это значит что fn принимает 4ре параметра типа double и возращает double.

Просто где то в других методах я говорю что:

C++
1
fn = &ExpressionCalculator::f3;
например
Bers
Заблокирован
06.11.2011, 22:45     CALLBACK. Нужна помощь #4
приведите весь код
-=ЮрА=-
Заблокирован
Автор FAQ
06.11.2011, 23:09     CALLBACK. Нужна помощь #5
atomohod, как вариант
C++
1
double tmp = &fn(a,b,c,d);
Цитата Сообщение от Bers Посмотреть сообщение
приведите весь код
- без этого непонятно что к чему
atomohod
 Аватар для atomohod
20 / 20 / 1
Регистрация: 01.04.2010
Сообщений: 57
07.11.2011, 00:03  [ТС]     CALLBACK. Нужна помощь #6
спасибо, вот код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#pragma once
#include <math.h>
#include <iostream>
 
enum Errors 
{ 
    DivBy0, 
    Negative,
    InvalidLgArgument
};
 
class CalculatingError
{
private:
    void Negative();
    void DivBy0();
    void InvalidLgArgument();
 
    Errors _error;
 
public: 
 
    CalculatingError(Errors error);
    ~CalculatingError();
 
    void RaiseError();
 
};
 
class ExpressionCalculator
{
private:
    double(ExpressionCalculator::*f)(double,double,double,double);
public:
    ExpressionCalculator(void);
    ~ExpressionCalculator(void);
 
    double f1(double a, double b, double c, double d);
    double f2(double a, double b, double c, double d);
    double f3(double a, double b, double c, double d);
 
    double Calculate(double a, double b, double c, double d);
 
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "ExpressionCalculator.h"
 
CalculatingError::CalculatingError(Errors error)
{
    _error = error;
}
void CalculatingError::RaiseError()
{
    switch(_error)
    {
    case Errors::DivBy0:
        DivBy0();
        break;
    case Errors::Negative:
        Negative();
        break;
    case Errors::InvalidLgArgument:
        InvalidLgArgument();
        break;
    }
}
CalculatingError::~CalculatingError()
{
 
}
void CalculatingError::Negative()
{
    std::cout << "Negative number in sqrt function" << std::endl;
}
void CalculatingError::DivBy0()
{
        std::cout << "Divide by zero" << std::endl;
}
void CalculatingError::InvalidLgArgument()
{
std::cout << "Invalid x in lg(x)" << std::endl;
}
 
 
 
ExpressionCalculator::ExpressionCalculator(void)
{
 
}
ExpressionCalculator::~ExpressionCalculator(void)
{
 
}
double ExpressionCalculator::f1(double a, double b, double c, double d)
{
    f = &ExpressionCalculator::f1;
    double tmp;
    try
    {
        if (a < 0) throw CalculatingError(Errors::Negative);
        if (!(a / 4 - b)) throw CalculatingError(Errors::DivBy0);
        tmp = (2 * c - d + sqrt(23 * a)) / (a / 4 - b);
    }
    catch (CalculatingError ce)
    {
        ce.RaiseError();
    }
    return tmp;
}
double ExpressionCalculator::f2(double a, double b, double c, double d)
{
    f = &ExpressionCalculator::f2;
    double tmp;
    try
    {
        if (c < 0) throw CalculatingError(Errors::Negative);
        if (!(b - a / 2)) throw CalculatingError(Errors::DivBy0); 
        tmp = (c + 4 * d - sqrt(123 * c)) / (b - a / 2);
    }
    catch (CalculatingError ce)
    {
        ce.RaiseError();
    }
    return tmp;
}
double ExpressionCalculator::f3(double a, double b, double c, double d)
{
    f = &ExpressionCalculator::f3;
    double tmp;
    try
    {
        if ((c - 5) < 0 || (c - 5) == 1) throw CalculatingError(Errors::InvalidLgArgument);
        if (!d) throw CalculatingError(Errors::DivBy0);
        if (!(a - b)) throw CalculatingError(Errors::DivBy0);
        tmp = (4 * log(c - 5) - 2 * d + 23) / (a - b);
    }
    catch (CalculatingError ce)
    {
        ce.RaiseError();
    }
    return tmp;
}
 
double ExpressionCalculator::Calculate(double a, double b, double c, double d)
{
    double tmp = &f(a,b,c,d);
    return 0;
}
Bers
Заблокирован
07.11.2011, 00:23     CALLBACK. Нужна помощь #7
не вижу точки входа в программу
atomohod
 Аватар для atomohod
20 / 20 / 1
Регистрация: 01.04.2010
Сообщений: 57
07.11.2011, 00:30  [ТС]     CALLBACK. Нужна помощь #8
вся прога большая. это отдельный класс. в методе main() просто создается экземпляр этого класса. код просто не компилируется
Bers
Заблокирован
07.11.2011, 00:39     CALLBACK. Нужна помощь #9
Цитата Сообщение от atomohod Посмотреть сообщение
вся прога большая. это отдельный класс. в методе main() просто создается экземпляр этого класса. код просто не компилируется
Я понимаю, смысл в том, что бы я мог скопипастить, и скомпилить у себя. А потом уже разбираться, что не так.

Мне нужно знать точно, как класс предполагается использовать. И проще будит спросить у автора пример кода с использованием, чем самому догонять как должно работать нечто, что даже не компилируется.

Поэтому, сделайте так: откройте отдельный мини-проектик. Перенесите в этот проектик только то, что относится к делу. Выложите сдесь.

Будим тестировать и выяснять. Желательно, если код будут сопровождать комментарии (что бы было понятно сразу, что делают методы классов, и зачем эти классы вообще нужны)
atomohod
 Аватар для atomohod
20 / 20 / 1
Регистрация: 01.04.2010
Сообщений: 57
07.11.2011, 00:59  [ТС]     CALLBACK. Нужна помощь #10
Спасибо огромное!

Проэкт и задание в attach'e.

Из задание (что в pdf) этот проэкт относится к 7му пункту (на 5й странице pdf'ки).
Вложения
Тип файла: zip exceptions.zip (5.82 Мб, 8 просмотров)
Bers
Заблокирован
07.11.2011, 01:23     CALLBACK. Нужна помощь #11
atomohod , мне нужны три файла:

1. ExpressionCalculator.h //тестируемый класс
2. ExpressionCalculator.cpp //реализация класса
3. main.cpp //здесь не должно быть ничего лишнего. Только пример работы тестируемого класса, иллюстрирующий неполадку.


Мне не нужен весь проект целиком. Мне не нужен main.cpp с километровой простыней кода.
Мне не нужны студийные файлы, тем более, что у меня нет студии, с помощью которой я смог бы открыть солюшен.

Мне нужны только три файла.
atomohod
 Аватар для atomohod
20 / 20 / 1
Регистрация: 01.04.2010
Сообщений: 57
07.11.2011, 01:35  [ТС]     CALLBACK. Нужна помощь #12
есть такое дело =)
Вложения
Тип файла: zip exc.zip (1.6 Кб, 7 просмотров)
Bers
Заблокирован
07.11.2011, 02:03     CALLBACK. Нужна помощь #13
atomohod, о том, какие роли выполняют классы, и что означают из методы аля f1(), f2() - это пусть каждый сам догадывается, да?


Ладно... итак...


C++
1
2
3
4
5
double ExpressionCalculator::Calculate(double a, double b, double c, double d)
{
    double tmp = &f(a,b,c,d); //чего автор хотел добиться этой строчкой?
    return 0;
}
atomohod
 Аватар для atomohod
20 / 20 / 1
Регистрация: 01.04.2010
Сообщений: 57
07.11.2011, 02:08  [ТС]     CALLBACK. Нужна помощь #14
f1() и f2() это функции, которые в 7 задании в пдф.

я хотел, получить значение функции, которая была вызвана последней для данного объекта, передав ей соответсвующие значения a, b, c, d.

т.е. создав объект ExpressionCalculator и вызваз у него f1() например, указатель *f указывает на эту функцию, которая была вызвана, и потом, вызвав метод Calculate(...) я могу не зная то какая функция вызывалась последней, получить нужное значение.

я только учусь, и возможно это можно сделать проще и логичней. В этом проекте я просто разбираюсь с callback
Bers
Заблокирован
07.11.2011, 05:47     CALLBACK. Нужна помощь #15
Честно говоря, я так и не понял, что за проблема такая. Мне самому интересно разобраться.
Я локализировал проблему:


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class CTest
{
    typedef void( CTest::*ptrFunc)(int Val);    
public:
    CTest() {  myfunc = &CTest::Test;  }
    
    void Start(int Val) { myfunc(Val);  } //error C2064: результатом вычисления 
                                                   //фрагмента не является функция, 
                                                   //принимающая 1 аргументов
private:
    void Test(int Val)    {  std::cout<< "Val = "<<Val<<std::endl;    }
    ptrFunc myfunc;
};
 
 
int main (void)
{
    CTest test;
    test.Start(30); 
 
    EndProgramm();
}
Добавлено через 21 минуту
дальнейший анализ проблемы:

Этот код уже компилируется:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//вынес имя указателя на функцию-метод за пределы класса, 
//что бы можно было создавать указатель за пределами класса
class CTest;
typedef void( CTest::*ptrFunc)(int Val);    
                                                            
 
class CTest
{
public:
    //инициализация указателя для тестов
    CTest() {  myfunc = &CTest::Test;  } 
    
   //пример того, как запустить метод класса для объекта изнутри класса
    void Start(int Val)   {  (this->*myfunc)(Val);                 }   
 
    //этот метод должен быть по итогу запущен
    void Test(int Val)    {  std::cout<< "Val = "<<Val<<std::endl; } 
private:
 
    //объявление указателя на метод в качестве данных-членов
    ptrFunc myfunc;  
};
 
 
int main (void)
{
    CTest test;
 
    //пример объявления указателя на функцию-метод извне класса
    ptrFunc myPtr=&CTest::Test; 
   
    //пример запуска метода на который указывает указатель извне класса
    (test.*myPtr)(10);   
 
 
    //этот метод запустит метод на который указывает указатель изнутри класса
    test.Start(30);  
 
    return 0;
}
Добавлено через 8 минут
Ну вроде разобрался более менее. Сейчас буду заводить код Топик-Стартера.
Должен будит хотя б скомпилироваться. Но подозреваю, что там помимо паленного синтаксиса есть ещё один серьёзный фейл

Добавлено через 38 минут
Обрати внимание, как я объявил указатель на метод класса.
Я использовал typedef что бы улучшить читабельность кода

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class ExpressionCalculator
{
public:
    ExpressionCalculator(void);
    ~ExpressionCalculator(void);
 
    double f1(double a, double b, double c, double d);
    double f2(double a, double b, double c, double d);
    double f3(double a, double b, double c, double d);
 
    double test(double a) { return 0;}
    double Calculate(double a, double b, double c, double d);
private:
    typedef double (ExpressionCalculator::*ptrFunc)(double a,double b,double c,double d);
 
    ptrFunc f; //так же нагляднее и понятнее объявлять указатель?
 
    //double(ExpressionCalculator::*f)(double,double,double,double);
};
Далее сам метод (исправлен, все компилируется)

C++
1
2
3
4
5
double ExpressionCalculator::Calculate(double a, double b, double c, double d)
{
    double tmp= (this->*f)(a,b,c,d);
    return tmp;
}
Здесь происходит следующее:
1. Идёт обращение к указателю, который указывает на метод класса
2. Запускается этот метод класса для объекта, на который указывает this
3. И результат работы этого метода записывается в переменную tmp

Собака была зарыта в том, что не_статический метод класса не может быть запущен сам по себе.
Он всегда запускается для какого то конкретного экземпляра класса.
И нужно компилятору обязательно знать this объекта, для которого сработает метод, на который указывает указатель.

Добавлено через 22 минуты
точнеее... все немножко иначе...

Когда мы хотим запустить не_статический метод класса, мы должны указатель компилятору для какого объекта мы его запускаем. Например:

ptrObj -> Method();

Зная тип указателя, и зная, что указатель указывает на начало объекта, компилятор догадается какую именно функцию и для какого объекта нужно запустить.

Указатель на метод класса содержит указатель на сам метод, но не знает, для какого именно из объектов этот метод нужно запустить.

*ptrFunc(); // эта запись эквивалентна вызову Method(); для класса. Но компилятору нужно знать для какого объекта метод запускается!

(ptrObj->*ptrFunc)(); //эквивалентна ptrObj -> Method();

Читать её нужно так: Для объекта, на который указывает ptrObj, запустить метод на который указывает ptrFunc, с аргументами, которые стоят в скобках. (в моём примере там ничего не стоит)

Добавлено через 28 минут
Можно ещё глубже проанализировать эту картинку:

допустим мы хотим объявить указатель на обычную функцию:
C++
1
2
3
4
5
6
7
8
9
10
void Foo() { std::cout << "YES!\n";}  //наш подопытный кролик
typedef void (*myPtr)();   //псевдоним для улучшенной читабельности
 
int main()
{
    myPtr test;  //создадим указатель на функцию
    test=&Foo;    //присвоим указателю значение функции
    (*test)();      //запустим на выполнение функцию, на которую указывает указатель
    return 0;
}

Из примера видно, что запись (*test)();
Компилятор заменит на Foo();

То бишь, в качестве имени функции будит выступать значение указателя, а то что в скобочках так и останется

Что происходит с указателем_на_метод класса?
Абсолютно тоже самое! Вместо указателя_на_метод компилятор подставит имя реального метода, скормив ему те же самые аргументы.

Проблема в том, что не_статический метод класса сам по себе вызвать нельзя. Компилятор должен знать для какого объекта он его вызывает.

Поэтому в записи:

(Объект.*Указатель)() компилятор сначала *Указатель подменит на реальное имя метода класса

Получится (Объект.Метод)()

Если же объект не указать - будит ошибка компиляции.

Исходя из всего выше изложенного можно сделать удивительный вывод.
Оказывается, запись: (Объект.Метод)(); работает!!!

Этот код компилируется:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Ctest
{
public:  void Foo() { std::cout << "YES!\n";}
};
 
int main()
{
    Ctest test;
    
    test.Foo(); //все нормальные люди пишут так
    (test.Foo)(); //оказывается, так писать тоже можно
 
    return 0;
}
/зы не жалею что потратил на этот новый для меня материал несколько часов. Хотя пришлось мало-мало погуглить-шмуглить и отфильтровать кучу хлама.

/зыы Уважаемые модераторы, ваш форум жосско глючит этой ночью. Вот, шоб вы знали.

Добавлено через 19 минут
Цитата Сообщение от atomohod Посмотреть сообщение
C++
1
double tmp = fn(a,b,c,d);
получаю при компиляции

error C2064: результатом вычисления фрагмента не является функция, принимающая 4 аргументов
подскажите, что не так?
Подозреваю, что результатом вычисления фрагмента является функция, принимающая 5 аргуметов! И этот пятый аргумент - это указатель this
Интересно, а можно как нибудь его так подсунуть функции, прям в качестве аргумента этой функции?

Сейчас попробую...

Добавлено через 7 минут
Нет... напрямую закатать this в сам аргумент функции не получилось. Фокус не прошёл. Компилятор на такое сразу нафег послал.
atomohod
 Аватар для atomohod
20 / 20 / 1
Регистрация: 01.04.2010
Сообщений: 57
07.11.2011, 11:17  [ТС]     CALLBACK. Нужна помощь #16
Bers, огромнейшее вам спасибо! Разобрался сам и новичкам скилап жесткий сделал! Такое объяснение было бы неплохо в FAQ по CALLBACK'ам записать!
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
07.11.2011, 11:40     CALLBACK. Нужна помощь #17
Bers, всё немного не так. В вашем тексте постоянно фигурирует "компилятор подменит xxx на реальное имя метода". Он такой ерундой заниматься вряд ли будет (если и будет, то только в целях оптимизации). Вот, скажем так, контрпример:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
 
class Foo
{
public:
    void func1() const
    {
        std::cout << "Foo::func1()" << std::endl;
    }
 
    void func2() const
    {
        std::cout << "Foo::func2()" << std::endl;
    }
 
    void func3() const
    {
        std::cout << "Foo::func3()" << std::endl;
    }
};
 
int main()
{
    typedef void (Foo::*func_ptr)() const;
 
    func_ptr arr[] = {&Foo::func1, &Foo::func2, &Foo::func3};
 
    Foo obj;
 
    while (true)
    {
        int what;
 
        do
        {
            std::cout << ">: ";
            std::cin >> what;
        }
        while (!(what >= 1 && what <= 3));
 
        (obj.*arr[what - 1])();
    }
 
    return 0;
}
Компилятор не сможет тут ничего подменить, ибо он заранее не знает, какой конкретно метод будет вызван, однако всё компилируется и работает.

Вся же проблема была в том, что, действительно, вызывать метод через указатель надо специальным оператором ->* (для указателя на объект класса) или .* (для ссылки или самого объекта).
Bers
Заблокирован
07.11.2011, 18:08     CALLBACK. Нужна помощь #18
silent_1991, понятно, что я утрирую для понимания именно с точки зрения высокоуровневого программиста, а не с точки зрения низко-уровневой механики.

Я сейчас объясню:

Вот смотрите, допустим у нас есть объект, и есть указатель на этот объект. Тогда доступ к объекту через указатель делается так:

ptr -> Method();

Или вот так:

(*ptr).Method();

Во втором варианте в скобочках вычисляется выражение, а именно, "взятие значение по адресу"

Вопрос: что такое "значение по адресу" ?

Ответ на этот вопрос зависит от уровня программиста.
Высокоуровневый программист, вроде меня скажет:

Ответ: данные, чей тип совпадает с типом указателя, который на них указывает.

Ну то есть вместо (*ptr) будит подставлен сам объект, который живет по адресу на который указывает ptr

С указателями на функцию абсолютно аналогично.

Понятно, что с точки зрения низкоуровневого программиста понятие "значение по адресу" может быть более точным, и менее абстрактным.

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

А в записи: (obj.*ptrFunc)() на самом деле происходят два действия:
1. *ptrFunc высчитывает идентификатор функции (адрес её исполняемого кода)
2. Запуск этой функции, с передачей ей в качестве дополнительного аргумента this объекта

Как то так.


/зы На самом деле на высоком уровне такие нюансы реально знать не нужно.
Если программист реально хочется поднять свой скилл, и во всем этом досканально разбираться, то ему нужно учить ассемблер, а не пытаться втиснуть в высокоуровневые рамки низкоуровневые абстракции, имхо.
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
07.11.2011, 21:44     CALLBACK. Нужна помощь #19
Bers, с моей точки зрения, язык С++ немного отличается от других языков в этом плане. Сейчас объясню. Я, конечно, на 100 процентов не уверен, но, на мой взгляд, относительно куда меньше программистов на джаве или на шарпе относительно программистов на С++ знают механизм реализации, скажем, виртуальных функций. Они пишут на высоком уровне и им по барабану, что вообще существуют указатели, что также существуют ещё и указатели на функции, и что эти указатели можно собирать в таблицу и заставлять указывать на методы класса. У них есть виртуальные методы как данность, и они ей пользуются. И это, вообще говоря, замечательно. С++ же несколько иной. Хочешь-не хочешь, а он заставит тебя разобраться в этих деталях, если ты хоть немного хочешь понимать, что же там происходит. Мы в этой теме обсуждаем указатели на методы класса, так о каком таком высоком уровне может идти речь?
В общем, моё мнение такое: если браться объяснять кому-либо что-либо, то надо объяснять это корректно и в деталях, а не абстрактно и перевирая истину.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.11.2011, 22:13     CALLBACK. Нужна помощь
Еще ссылки по теме:

Нужна помощь C++
C++ Нужна помощь
For_each и аргументы callback-функции; Как передать callback'у больше одного аргумента C++

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

Или воспользуйтесь поиском по форуму:
Bers
Заблокирован
07.11.2011, 22:13     CALLBACK. Нужна помощь #20
Хорошо. Я согласен с вами. но ответьте мне на такой вопрос:

C++
1
2
3
4
5
6
7
8
9
10
void Foo() { std::cout << "YES!\n";}  //наш подопытный кролик
typedef void (*myPtr)();   //псевдоним для улучшенной читабельности
 
int main()
{
    myPtr test;  //создадим указатель на функцию
    test=&Foo;    //присвоим указателю значение функции
    (*test)();      //запустим на выполнение функцию, на которую указывает указатель
    return 0;
}
В с++ любое выражение в скобках "высчитывается", и вместо этого выражения подставляется результат расчетов.

в лексеме (*test) ()

что будит поставлено вместо *test ?

На самом деле? Я предполагаю - идентификтор имени функции, который является ни чем иным, как указателем на начало блока памяти, в котором записаны исполняемые инструкции машины.

Но если я прав, тогда в чем же я приверал? А если я не прав - объясните мне, в чем я не прав, что бы я знал.
Yandex
Объявления
07.11.2011, 22:13     CALLBACK. Нужна помощь
Закрытая тема Создать тему
Опции темы

Текущее время: 16:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru