gpt4 book ai didi

c - GTK接口(interface)结构: Why is it built as casting interface?

转载 作者:行者123 更新时间:2023-11-30 19:01:25 25 4
gpt4 key购买 nike

GTK3 提供了使强制转换成为必要的功能。如

gtk_grid_attach(GTK_GRID(grid), button, 0,0,0,0)

但是,此方法将始终采用网格。那么为什么强制类型转换不在函数内部呢?该调用将变为:

gtk_grid_attach(grid, button, 0,0,0,0)

因此会更短且更容易阅读(因为没有冗余)。

编辑:

由于评论中的讨论,我将尝试使用下面 David Ranieri 的示例使我的问题更清楚

给定代码:

 typedef struct {char *sound;} animal_t;
typedef struct {animal_t animal; char *name;} dog_t;
typedef struct {animal_t animal;} cat_t;

#define DOG(animal) (dog_t *)animal
#define CAT(animal) (cat_t *)animal

有两种方法可以实现函数dog_print_name而不丢失类型检查机制。在下面的示例中,我将交出一只,而应该交出一只狗。

(1)

 void dog_print_name(dog_t *dog)
{
puts(dog->name);
}

int main(){
// ...
dog_print_name(DOG(cat)); // perfom type check here
// and fail on 'cat'
}

(2)

 void dog_print_name(void *dog)
{
dog_t *dog_ = DOG(dog); // check performed
// will fail, if 'dog' is a cat.
puts(dog->name);
}

int main(){
// ...
dog_print_name(cat); // no check performed here
}

给出了这两段代码,选择实现(1)而不是实现(2)的原因是什么?目标是在需要 dog 但给出了 cat 的调用中获得警告/错误。

最佳答案

这是必需的,因为 C 不处理多态性。它无法根据类层次结构检查该参数的类型是否有效。因此,宏会触发对此进行检查,并确保即使您将指针存储为正确的指针类型,它指向的内容(GObject 派生对象)也使用正确的类型。

这里,grid 具有正确的类型,但不具有正确的内容。进行显式检查使调试变得更加容易。

GtkGrid *grid = gtk_image_new(); 
GtkButton *button = gtk_button_new();
gtk_grid_attach(grid, button, 0,0,0,0); // Won't catch early the fact that grid is a GtkImage, not a GtkGrid.

此外,大多数时候,您只需将所有内容声明为指向 GtkWidget 的指针。这是因为根据您调用的方法,它们来自的类可能会有所不同,因此您无论如何都需要进行强制转换。

GtkWidget *grid = gtk_grid_new(); 
GtkWidget *button = gtk_button_new();
gtk_grid_attach(GTK_GRID(grid), button, 0,0,0,0); // WILL check at runtime that grid is a GtkGrid.
gtk_grid_remove_row(GTK_GRID(grid), 0);
gtk_container_add(GTK_CONTAINER(grid), button);

关于c - GTK接口(interface)结构: Why is it built as casting interface?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57865478/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com