在研究ooc(面向对象C)的概念证明时,我偶然发现了一件我无法理解效果和意图的作品。这本书是由Axel Schreiner编写的,他已经退休了一段时间并表示他不想深入研究c代码。所以我在这里提出我的问题。
编辑:我标记了答案,表明我的解释错误。 chux的评论为+1,4386427的答案为+1。有问题的代码是:
{
typedef void (* voidf) ();
voidf selector;
va_list ap = * app;
/* generic function pointer */
while ((selector = va_arg(ap, voidf)))
{
voidf method = va_arg(ap, voidf);
if (selector == (voidf) ctor)
* (voidf *) & self —> ctor = method;
else if (selector == (voidf) dtor)
* (voidf *) & self —> dtor = method;
else if (selector == (voidf) differ)
* (voidf *) & self —> differ = method;
else if (selector == (voidf) puto)
* (voidf *) & self —> puto = method;
}
return self;
}}
它的目的是用这个类的特定函数覆盖继承的函数。电话可能是
if (! PointClass)
PointClass = new(Class, "PointClass",
Class, sizeof(struct PointClass),
ctor, PointClass_ctor,
0);
if (! Point)
Point = new(PointClass, "Point",
Object, sizeof(struct Point),
ctor, Point_ctor,
draw, Point_draw,
0);
有趣的是像ctor, Point_ctor
这样的代码,两者都是函数指针(在本例中是构造函数)。有问题的代码处理呼叫。
我对代码的问题在于行(不同的情况):
else if (selector == (voidf) differ)
* (voidf *) & self —> differ = method;
最后一行derefences voidf *
(其中voidf是一个通用函数指针,请参阅typedef)并执行二进制和('&') - >不同,然后分配方法不同。
我得到self->differ
函数指针被覆盖,但是:
voidf *
(voidf已经是指针)?我已经尝试了他的例子,但它们似乎有效,但这两件事我不明白:有人可以帮我理解这里发生了什么吗?
P.S。我确实得到了一个非常严肃的编译器警告"解除引用类型惩罚指针会破坏严格别名规则"可能是指泛型指针的derefence。
亲切的问候,Guus。
答案 0 :(得分:1)
为什么取消引用voidf *(voidf已经是一个指针)?
voidf
不是指针。这是一种类型。您不能取消引用某种类型。
(voidf *)
是演员。
为什么要使用二进制和('&')?它做了什么?
它不是“二元和”。它是地址。
所以一般来说你读错了代码。阅读它:
* ((voidf *) (&(self —>differ))) = method;