Указатели на функции и возвращаемый тип

259
08 ноября 2017, 02:41

Изучаю C++. остановился на теме "Указатели на функции".

Есть код работающий.

#include <iostream>
using namespace std;
double add(double, double);
double multi(double, double);
double divorce(double, double);
const double* calculate(double, double, double (*pr[3])(double, double));
double  (*pf[3])(double, double) = {&add, &multi, &divorce};
int main()
{
    const double* q = calculate(2.5, 10.4, pf);
    cout << endl;
    for (int i = 0; i < 3; ++i)
    {
        cout << q[i] << endl;
    }
    return 0;
}
double add(double x, double y)
{
    return x + y;
}
double multi(double x, double y)
{
    return x * y;
}
double divorce(double x, double y)
{
    return x / y;
}
const double* calculate(double x, double y, double (*pr[3])(double, double))
{
    auto* ptr = new double[3];
    for (int i = 0; i < 3; ++i)
    {
        ptr[i] = (*pr[i])(x, y);
    }
    return ptr;
}

Если поменять строки

double add(double, double);
double multi(double, double);
double divorce(double, double);

на

const double add(double, double);
const double multi(double, double);
const double divorce(double, double);

то тогда выражение double (*pf[3])(double, double) = {&add, &multi, &divorce}; нужно поменять на double (*pf[3])(double, double) = {add, multi, divorce};

Почему?

Да и еще один вопрос.

Объясните разницу между const double (*pf[3])(double, double) и double (*pf[3])(double, double)

Answer 1

Менять необходимо, так как сигнатура функции double add(double, double); не соответствует сигнатуре функции const double add(double, double);. Различие заключается в наличии const-квалификатора для возвращаемого значения. Причем для простых типов наличие этого const-квалификатора вообще-то не имеет смысла, а для объектов может быть большая разница, например если возвращать просто std::string x(void), то можно написать вот так x().append("oops");.

Answer 2

У Вас в коде два разных типа, с одной стороны Вы объявляете массив, в который можно помещать объекты такого типа: double(*)(double, double), с другой Вы пытаетесь поместить в этот массив функцию add (к примеру), а тип этого выражения будет такой: const double(*)(double, double). Разумеется, что это два разных типа, и Вы не можете просто взять и поместить объект одного типа в массив, который содержит объекты другого типа.

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

READ ALSO
Как проверить пиксели в QGraphicsScene? [требует правки]

Как проверить пиксели в QGraphicsScene? [требует правки]

(есть точка или нет) Устанавливаю QGraphicsScene для QGraphicsView

323
Задача на поиск в ширину (bfs)

Задача на поиск в ширину (bfs)

Решаю задачу на BFSНа некоторых тестах неправильный ответ

283
Выдаёт - неправильно завершена декларация,помогите найти ошибку

Выдаёт - неправильно завершена декларация,помогите найти ошибку

Вот, исправил некоторые ошибки в Вашем коде, компилируется, выполняется

198
Метод касательных(Ньютона) [требует правки]

Метод касательных(Ньютона) [требует правки]

Не могу понять как реализовать этот метод на с++ Нашел много примеров программ но они полностью не подходят, помогите плизВот пример который...

392