C语言 C - 结构内的函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17052443/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 06:40:34  来源:igfitidea点击:

C - function inside struct

cfunctionstruct

提问by xRed

Im trying to create a function inside a structure, so far i have this code:

我试图在结构内创建一个函数,到目前为止我有这个代码:

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

        pno AddClient() 

        {
            /* code */
        }

};

int main()
{

    client_t client;

    //code ..

    client.AddClient();

}

Error: client.h:24:2: error: expected ‘:', ‘,', ‘;', ‘}' or ‘attribute' before ‘{' token.

错误client.h:24:2:错误:在“{”标记之前应为“:”、“、”、“;”、“}”或“属性”。

Which is the correct way to do it ?

哪个是正确的方法?

回答by FatalError

It can't be done directly, but you can emulate the same thing using function pointers and explicitly passing the "this" parameter:

它不能直接完成,但您可以使用函数指针并显式传递“this”参数来模拟相同的事情:

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

        pno (*AddClient)(client_t *);    
};

pno client_t_AddClient(client_t *self) { /* code */ }

int main()
{

    client_t client;
    client.AddClient = client_t_AddClient; // probably really done in some init fn

    //code ..

    client.AddClient(&client);

}

It turns out that doing this, however, doesn't really buy you an awful lot. As such, you won't see many C APIs implemented in this style, since you may as well just call your external function and pass the instance.

然而,事实证明,这样做并没有真正给你带来很多好处。因此,您不会看到许多以这种方式实现的 C API,因为您也可以只调用外部函数并传递实例。

回答by jxh

As others have noted, embedding function pointers directly inside your structure is usually reserved for special purposes, like a callback function.

正如其他人所指出的,直接在结构中嵌入函数指针通常保留用于特殊目的,例如回调函数。

What you probably want is something more like a virtual method table.

您可能想要的是更像虚拟方法表的东西。

typedef struct client_ops_t client_ops_t;
typedef struct client_t client_t, *pno;

struct client_t {
    /* ... */
    client_ops_t *ops;
};

struct client_ops_t {
    pno (*AddClient)(client_t *);
    pno (*RemoveClient)(client_t *);
};

pno AddClient (client_t *client) { return client->ops->AddClient(client); }
pno RemoveClient (client_t *client) { return client->ops->RemoveClient(client); }

Now, adding more operations does not change the size of the client_tstructure. Now, this kind of flexibility is only useful if you need to define many kinds of clients, or want to allow users of your client_tinterface to be able to augment how the operations behave.

现在,添加更多操作不会改变client_t结构的大小。现在,这种灵活性仅在您需要定义多种客户端或希望允许client_t界面用户能够增强操作行为方式时才有用。

This kind of structure does appear in real code. The OpenSSL BIO layer looks similar to this, and also UNIX device driver interfaces have a layer like this.

这种结构确实出现在实际代码中。OpenSSL BIO 层看起来与此类似,而且 UNIX 设备驱动程序接口也有这样一个层。

回答by QSQ

This will only work in C++. Functions in structs are not a feature of C.

这仅适用于 C++。结构体中的函数不是 C 的特性。

Same goes for your client.AddClient(); call ... this is a call for a member function, which is object oriented programming, i.e. C++.

同样适用于您的 client.AddClient(); call ...这是对成员函数的调用,是面向对象的编程,即C++。

Convert your source to a .cpp file and make sure you are compiling accordingly.

将您的源代码转换为 .cpp 文件并确保您进行了相应的编译。

If you need to stick to C, the code below is (sort of) the equivalent:

如果你需要坚持使用 C,下面的代码是(有点)等价的:

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

};


pno AddClient(pno *pclient) 
{
    /* code */
}


int main()
{

    client_t client;

    //code ..

    AddClient(client);

}

回答by rogal

How about this?

这个怎么样?

#include <stdio.h>

typedef struct hello {
    int (*someFunction)();
} hello;

int foo() {
    return 0;
}

hello Hello() {
    struct hello aHello;
    aHello.someFunction = &foo;
    return aHello;
}

int main()
{
    struct hello aHello = Hello();
    printf("Print hello: %d\n", aHello.someFunction());

    return 0;
} 

回答by Chris Reid

You are trying to group code according to struct. C grouping is by file. You put all the functions and internal variables in a header or a header and a object ".o" file compiled from a c source file.

您正在尝试根据结构对代码进行分组。C 分组是按文件的。你把所有的函数和内部变量放在一个头文件或一个头文件和一个从 ac 源文件编译的对象“.o”文件中。

It is not necessary to reinvent object-orientation from scratch for a C program, which is not an object oriented language.

没有必要为 C 程序从头开始重新发明面向对象,C 程序不是面向对象的语言。

I have seen this before. It is a strange thing. Coders, some of them, have an aversion to passing an object they want to change into a function to change it, even though that is the standard way to do so.

我以前见过这个。这是一件奇怪的事情。编码人员,其中一些人,厌恶将他们想要更改的对象传递为一个函数来更改它,即使这是这样做的标准方法。

I blame C++, because it hid the fact that the class object is always the first parameter in a member function, but it is hidden. So it looks like it is not passing the object into the function, even though it is.

我责怪 C++,因为它隐藏了类对象始终是成员函数中的第一个参数的事实,但它是隐藏的。所以看起来它没有将对象传递给函数,即使它是。

Client.addClient(Client& c); // addClient first parameter is actually 
                             // "this", a pointer to the Client object.

C is flexible and can take passing things by reference.

C 很灵活,可以通过引用传递事物。

A C function often returns only a status byte or int and that is often ignored. In your case a proper form might be

AC 函数通常只返回一个状态字节或 int 并且经常被忽略。在您的情况下,适当的形式可能是

 err = addClient( container_t  cnt, client_t c);
 if ( err != 0 )
   { fprintf(stderr, "could not add client (%d) \n", err ); 

addClient would be in Client.h or Client.c

addClient 将在 Client.h 或 Client.c 中