我有一个具有以下结构的类:
class Detection
{
public:
void processImage (cv::Mat& image);
void setGobalPositionCalculator (Point3D (*globalPositionCalculator) (float horizontalAngle, float verticalAngle));
private:
Point3D (*globalPositionCalculator) (float, float);
};
然后按如下方式声明方法:
void Detection::setGobalPositionCalculator (Point3D (*globalPositionCalculator) (float, float))
{
this->globalPositionCalculator = globalPositionCalculator;
}
void Detection::processImage(Mat& image)
{
if (globalPositionCalculator)
{
landmark.position = globalPositionCalculator (hAngle, vAngle);
}
}
问题1:
我看不懂setGobalPositionCalculator()
的"Argument"格式。我总是看到用comma( , )
问题2:
globalPositionCalculator
不是类的成员变量,那么processImage()
怎么能访问它呢?
问题1
你看到的参数是一个function pointer
,下面所有的都是一个function pointer
Point3D (*globalPositionCalculator) (float horizontalAngle, float verticalAngle)
它是说这个指针,指向一个具有以下特征的方法:
Point3D methodName(float horizontalAngle, float verticalAngle);
// ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Return type^ arguments
globalPositionCalculator
是指向methodName
的指针
查看cprogramming
中的基本示例#include <iostream>
void my_int_func(int x)
{
std::cout << x << std::endl;
}
int main()
{
void (*foo)(int);
foo = &my_int_func;
/* call my_int_func (note that you do not need to write (*foo)(2) ) */
foo( 2 );
/* but if you want to, you may */
(*foo)( 2 );
return 0;
}
问题2
您必须在 setGobalPositionCalculator
之后调用processImage
方法,这是强制性的,否则不会发生任何事情。
如果你仔细看setGobalPositionCalculator
// I changed the function pointer variable name to add clarity to this example
void Detection::setGobalPositionCalculator (Point3D (*thefunctionpointer) (float, float))
{
// In the next line a member variable of the Detection
// object is set to the pointer you just passed
// they are different variables
this->globalPositionCalculator = thefunctionpointer;
}
现在当你到达下一个方法
void Detection::processImage(Mat& image)
{
// you are checking the private member
if (this->globalPositionCalculator)
{
landmark.position = this->globalPositionCalculator (hAngle, vAngle);
}
}
当然,他们删除了this
指针,因为它没有任何作用。但是正如您所看到的,它增加了代码的清晰度。
This:
void Detection::setGobalPositionCalculator (Point3D (*globalPositionCalculator) (float, float))
也可以通过:
表示//// an "alias" used when this type of function pointer is needed a lot
typedef Point3D (*globalPositionCalculator) (float, float);
void Detection::setGobalPositionCalculato(globalPositionCalculator funct_ptr);
您所指的"成员"可以通过简单地调用function_ptr来访问:
Point3D myFunc(float x, float y); // declaration --> must be implemented
globalPositionCalculator atPos = NULL; // init
atPos = &myFunc; // this is basically what Detection::setGlobal[...] does.
float m_X, m_Y;
atPos(m_X, m_Y); // call function (e.g. with object params).
在课堂上:
class A {
public:
void setter(globalPositionCalculator func_ptr) { m_Ptr = funct_ptr; }
void callFunc() { if (m_Ptr != NULL) { m_Ptr(m_X, m_Y); }
private:
float x;
float y;
globalPositionCalculator m_Ptr;
};
globalPositionCalculator
是指向函数的指针,该函数获得两个float
数字,并返回Point3D
。为了更好地理解,你可以从这里开始阅读Function_pointer
写这个class
的人实际上希望你知道global Position
将如何计算,所以你需要用给定的原型编写一个函数,并将其作为参数传递给setGobalPositionCalculator
方法,然后他在处理图像时使用该逻辑来计算地标位置。
编辑:回复你的评论
代码指令有地址。函数名实际上是函数第一条指令的地址。在这个类的某个地方应该有函数指针globalPositionCalculator
的定义。语句
`this->globalPositionCalculator = globalPositionCalculator;`
将某个知道如何计算全局位置的逻辑块的地址赋给类成员globalPositionCalculator
,该成员是指向函数的指针。之后在processImage
方法中,程序将跳转到这段代码,处理它并获取它的返回值,processImage将继续其流程。
void Detection::setGobalPositionCalculator (Point3D (*globalPositionCalculator) (float, float))
是指向一个函数的指针,该函数需要两个float
作为参数,并返回一个Point3D
。
使用例子:
Point3D foo(float f1, float f2)
{
Point3d p;
// Do the necessary calculations to set the data
// of p by using f1 and f2
return p;
}
Detection d;
d.setGlobalPositionCalculator(foo);