2014-10-28 3 views
2

Я пытаюсь создать калькулятор скорости и времени, который является настолько эффективным, насколько это возможно, и хотел бы ссылаться на вызов функции с использованием указателя, который изменяется в соответствии с вводом но я не уверен, как это сделать. Я пробовал много разных вещей:Вызов функции без явного обращения к ней, который изменяется в соответствии с вводом

Моей лучшую попытку:

// Inside class Math 
double calcSpeed(double distance, double time); // These functions return a double value of the formula (non static) 
double calcDistance(double speed, double time); 
double calcTime(double speed, double distance); 

// Inside Main 
typedef double (Math::*FuncChosen)(double first, double second); 
FuncChosen p = &Math::calcSpeed; // This changes according to input to different functions in Math class with same parameter types and return types 
p(1, 2); // Not a function, how can I non explicitly call the function? 

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

Спасибо заранее,

И, да, я новичок в C++ и не сделал много с указателями/ссылками и памятью.

Edit: Для справки, законченный, полный code после коррекции - компилируемых

+0

Почему бы не сделать функции в классе Math статические, или их нет в классе вообще? (Они все еще могут находиться в пространстве имен) –

+0

Wow, я продолжаю получать const и статические смущения. Думаю, я, наверное, мог бы сделать их статичными, но я думаю, я думал, что должен все это знать. Думаю, оставляя их не статическими, у меня больше гибкости? Кроме того, это был в основном проект, включающий несколько разных идей, которые я узнал, поэтому я хотел поместить его в отдельный класс частично по этой причине, а также выглядеть немного чище. tl; dr: Возможно, я мог бы сделать одну из этих вещей, но в какой-то момент мне все равно придется это выяснить. – exitcode

+0

Единственное, что нужно математике, это поток строк, но я не уверен, для чего он используется. Сделайте Math пространство имен и удалите поток. –

ответ

5

Вы не включили MCVE, но комментарии и код указывают на функции не являются статическими функциями членов внутри класса Math. Тип FuncChosen является указателем для функции-члена.

Указатели на членов странных зверей. На самом деле это не указатель, поскольку он не указывает на что-либо прямо. Подумайте о указателе на член как «идентификатор внутри класса». Таким образом, p идентифицирует определенную функцию-член (например, calcSpeed). Так же, как обычно вы можете вызвать функцию-член только путем вызова ее на объект, вам необходимо предоставить объект для вызова через указатель на член. Так, например, если у вас есть этот код:

Math m; 
double res = m.calcSpeed(1.0, 2.0); 

Тогда эквивалентная с указателем на член p будет:

Math m; 
FuncChosen p = &Math::calcSpeed; 
(m.*p)(1.0, 2.0); 

Оператор .* (и соответствующий ->*) используются для разыменования указателя на элемент.


Для полноты: Вышеупомянутое относится к нестационарным функциям-членам. Если calcSpeed и т. Д. Были статические функции, вместо этого вы должны были бы использовать обычные указатели на функции, чтобы ссылаться на них.

+0

Спасибо за ответ, и он, похоже, сработал, но это, вероятно, не связанная с этим проблема, я просто попробовал это и получил эти ошибки компилятора: https: // gist .github.com/exitcode/0948341a1557c27412f0 – exitcode

+0

Это другая проблема, и она требует реализации функции 'calcSpeed'. – Ajay

+0

@SharkyDoesCode Да, это не связано. Это не ошибка компилятора, это ошибка компоновщика. Он жалуется, что не имеет доступа к определениям функций. Либо вы не определили их, либо не связываетесь в содержащем их объектном файле. Вы можете найти некоторую помощь в этом вопросе [FAQ] (http://stackoverflow.com/q/12573816/1782465). – Angew

2

Нестатическая функция не может быть вызвана без объекта. Ответьте на это: вы можете позвонить calcSpeed вот так?

calcSpeed(10.4, 444.0); 

Нет. Потому что ему нужен объект слева.

Math o; 
o.calcSpeed(10.4, 444.0); 

Вы можете держать адрес для этого метода, но вы должны вызвать его с помощью объекта:

(o.*p)(10.4, 444.0); 

ADD

Если объект называется указателем (Math* po = &o;), необходимо использовать оператор ->*:

(po->*p)(10.4, 444.0); 

Что же, как:

((*po).*p)(10.4, 444.0); 
Смежные вопросы