【问题标题】:Accessing members inside struct with member function? [duplicate]使用成员函数访问结构内的成员? [复制]
【发布时间】:2016-11-14 01:38:13
【问题描述】:

假设我有以下结构

struct Being{
    int canFly;
    int (*printFlying)();
}

我想做如下的事情:

int main(){
    struct Being * flyingThing = new_flyingThing();
    struct Being * thingThatCantFly = new_Thing();

    flyingThing->printFlying(); /* "I'm flying!" */
    thingThatCantFly->printFlying(); /* "I can't fly!" */
}

看起来我需要printFlying函数才能访问结构中的canFly变量,但我不知道该怎么做,或者这是否可能。

有没有办法让我的代码做我想做的事?谢谢!!


我在 cmets 中解释了为什么这个问题不是链接问题的重复。

【问题讨论】:

  • C 不是 Java。您似乎正在尝试在 C 中使用 OOP,但它并不是为它设计的。
  • 你需要给printFlying一个参数,它是指向相关对象的指针
  • new_flyingThing()new_Thing() 需要在成员中放置不同的功能,并且功能应该打印相应的消息。
  • @csTroubled 那是不可能的。在其他语言中,隐式 this 参数被传递给函数。在 C 中,您必须明确指定它。如果需要 OO 支持,请使用 C++。
  • 是的,您似乎正在尝试做一些对 OO 语言来说很正常的事情,但您不想使用 OO 语言。

标签: c


【解决方案1】:

对于这个特定的示例,您似乎真正想要的是能够拥有一个指向两个不同函数的函数指针,一个实现飞行,一个实现不飞行。

所以我会考虑的方法如下。我没有尝试实际编译这段代码,但这种感觉是正确的。

在您的 cmets 中,您还提到了防止更改函数指针。您可以执行以下操作,其中将 const 添加到函数指针的结构定义中,然后使用带有强制转换的结构的克隆。

头文件flying.h内容。

typedef struct _TAG_Being {
    int (* const printFlying)();
} Being;

Being * new_flyingThing ();
Being * new_Thing();

实现或flying.c文件。

#include "flying.h"

static int printFlyingThing()
{
    printf (" I am a flying thing\n");
    return 0;
}

static int printThing()
{
    printf (" I am a thing\n");
    return 1;
}

// use the same layout and members as Being above.
typedef struct {
    int (* printFlying)();
} BeingX;

Being * new_flyingThing ()
{
    BeingX *p = malloc(sizeof(BeingX));
    p->printFlying = printFlyingThing;  // use the flying thing function

    {
        Being *q = (Being *)p;
        return q;
    }
}

Being * new_Thing()
{
    BeingX *p = malloc(sizeof(BeingX));
    p->printFlying = printThing;       // use the not flying thing function.

    {
        Being *q = (Being *)p;
        return q;
    }
}

主要或使用 .c 文件

#include "flying.h"

int main(){
    Being * flyingThing = new_flyingThing();
    Being * thingThatCantFly = new_Thing();

    flyingThing->printFlying(); /* "I'm flying!" */
    thingThatCantFly->printFlying(); /* "I can't fly!" */
}

如果您需要在printFlying() 函数中访问实际的Being 对象或变量,那么您需要将其作为参数传递。

例如:

typedef struct _TAG_Being {
    int  xx;
    int (*printFlying)(struct _TAG_Being *p);
} Being;

那么你需要这样的东西:

Being * flyingThing = new_flyingThing();

flyingThing->printFlying(flyingThing); /* "I'm flying!" */

【讨论】:

    【解决方案2】:

    C 不是面向对象的语言,因此函数成员无法自动知道使用哪个结构来调用它。

    由于每个结构都有自己的函数指针,您可以通过让它们引用不同的函数来获得所需的结果,这些函数会打印相应的消息,而不是从can_fly 成员中获取。

    int print_flying_thing() {
        printf("I'm flying!\n");
    }
    struct Being *new_flyingThing() {
        struct Being *thing = malloc(sizeof(struct Being));
        thing->can_fly = 1;
        thing->printFlying = print_flying_thing;
        return thing;
    }
    
    int print_nonflying_thing() {
        printf("I can't fly!\n");
    }
    struct Being *new_Thing() {
        struct Being *thing = malloc(sizeof(struct Being));
        thing->can_fly = 0;
        thing->printFlying = print_nonflying_thing;
        return thing;
    }
    

    【讨论】:

    • 可以,但是函数仍然不能访问结构的成员。
    • @KeithThompson 没错,但平心而论,我打算用它来检查canFly 的值是真还是假。
    • 如果您将任何“oo”c 结构的第一个参数采用指向自身的指针作为标准(int (*printFlying)(Being *); 那么您遵循始终传递您关心的结构的过程:@987654325 @ 然后你可以在某种程度上模拟成员访问。
    • @Ben 他在 cmets 中写道,他不希望函数带参数。
    【解决方案3】:

    printFlying 指针所指向的函数不能访问包含struct Being 结构的成员,除非它被赋予一个引用该结构的参数。 (或者它可以通过其他方式访问结构,可能通过全局变量,但参数是最简洁的方式。)

    例如,考虑两个struct Being 类型的对象,它们的printFlying 指针都指向同一个函数。该函数无法判断它与两个对象中的哪一个相关联——因为它不与其中任何一个相关联。

    C++ 成员函数可以做到这一点,因为它们被赋予了一个隐式指针参数,通过 this 关键字在函数内部引用。 C 没有这个特性。

    您可能可以创建一个执行类似操作的宏,但我怀疑这是否值得。

    您是否考虑过只使用 C++?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 2021-11-13
      • 2023-03-16
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多