我有一个用C语言编写的代码示例,它模拟了虚函数Shape_area()。
我不懂一行代码:return (*me->vptr->area)(me);
为什么在“我”之前使用“ *”?
您能告诉我那部分吗? 谢谢
/*shape.h*/
struct ShapeVtbl; /* forward declaration */
typedef struct {
struct ShapeVtbl const *vptr; /* <== Shape's Virtual Pointer */
int16_t x; /* x-coordinate of Shape's position */
int16_t y; /* y-coordinate of Shape's position */
} Shape;
/* Shape's virtual table */
struct ShapeVtbl {
uint32_t (*area)(Shape const * const me);
};
/* Shape's operations (Shape's interface)... */
void Shape_ctor(Shape * const me, int16_t x, int16_t y);
void Shape_moveBy(Shape * const me, int16_t dx, int16_t dy);
uint32_t Shape_area(Shape const * const me) {
return (*me->vptr->area)(me);
}
答案 0 :(得分:6)
如果它是一个函数指针,则不是必需的。不管有没有,都一样。
这个想法是,它是一个“指向函数的指针”,因此您希望取消对指针的引用,以便能够将其用作函数。但是函数名称实际上实际上也只是指针,并且您也不需要取消引用它们,因此它们是等效的。
expected = pd.DataFrame({
'CREATED_DT_DTTM_EPOCH': [
1483302261,
1483305054,
1483357692,
1483385453,
1483391215
],
'Audit_Epoch': [0,1483383670,0,0,0],
'Difference': [
1483302261,
78616,
1483357692,
1483385453,
1483391215
]
})
等效于(*me->vptr->area)(me)
,而(me->vptr->area)(me)
等效于printf("foo")
(尽管您永远不会这样写)。
您可以保留它或将其删除,这并不重要。就个人而言,如果它专门是指向函数的指针而不是命名函数本身,那么我将保留它,以保持“取消使用它”的想法。
答案 1 :(得分:2)
函数Shape_area()定义为:
uint32_t Shape_area(Shape const * const me) {
return (*me->vptr->area)(me);
}
这意味着函数Shape_area()
接受一个指向Shape类型的结构的指针。
因此,为了获得虚拟函数的实际函数指针,各种结构的定义如下。
第一个结构是实际的数据结构,其中包含数据以及虚函数指针。
typedef struct {
struct ShapeVtbl const *vptr; /* <== Shape's Virtual Pointer */
int16_t x; /* x-coordinate of Shape's position */
int16_t y; /* y-coordinate of Shape's position */
} Shape;
有两个数据项x
和y
,以及指向虚拟指针的指针,该指针将包含指向要使用的实际函数的指针。
指向虚函数的指针包含一个结构,并定义为:
struct ShapeVtbl {
uint32_t (*area)(Shape const * const me);
};
因此,如果我们使用这些数据结构之一,它将类似于以下源代码片段。
uint32_t doVirt (Shape const * const me)
{
// do things with the x and y data from variable me.
// reference me->x and me->y to access those values.
return 0;
}
struct ShapeVtbl myVirt = { doVirt }; // create a struct containing pointer to our function
Shape myShape; // define our data structure
myShape.x = 32; // set the x coordinate
myShape.y = 45; // set the y coordinate
myShape.vptr = &myVirt; // set the pointer to the virtual function pointer.
Shape_area (&myShape); // call Shape_area with our struct.
函数Shape_area()
将指向myShape
结构的指针,然后访问通过提供的函数指针指定的虚函数。
如果我们查看operator precedence table,我们会发现*me->vptr->area
与*(me->vptr->area)
相同,或者换句话说,星号用于使用标准指针取消引用语法来取消引用功能指针。
但是对于函数指针,虽然仍然可以使用此语法,但这不是必需的。因此,由于运算符优先级规则,(*me->vptr->area)()
与(me->vptr->area) ()
相同,与me->vptr->area()
相同。