在多个文件中使用常量元素的多态结构
Polymorphic structure using constant element in multiple files
我现在正在学习 C 中的一些基本多态性。我尝试编写一个常量元素来保存一些方法指针,这些方法指针将被更高级别的结构继承。当我在一个文件中编写所有代码时它工作正常,这是所需的行为:
#include <stdio.h>
#include <string.h>
struct connection {
void (*connect)(struct connection self);
char name[16];
};
void connection_connect(struct connection self) {
printf("Connecting to %s\n", self.name);
}
const struct connection conn = {connection_connect};
typedef struct {
struct connection connection;
void (*setup)(char name[16]);
void (*connect)();
}__server;
__server server;
void server_setup(char name[16]) {
strcpy(server.connection.name, name);
}
void server_connect() {
server.connection.connect(server.connection);
}
__server server = {
conn, server_setup, server_connect
};
typedef struct {
struct connection connection;
void (*setup)(char name[16]);
void (*connect)();
}__client;
__client client;
void client_setup(char name[16]) {
strcpy(client.connection.name, name);
}
void client_connect() {
client.connection.connect(client.connection);
}
__client client = {
conn, client_setup, client_connect
};
int main(void) {
server.setup("Charlie");
client.setup("Delta");
server.connect();
client.connect();
return 0;
}
将所有结构移动到不同的文件时会出现问题。在这种情况下,我被迫 extern
我的连接头文件中的 struct connection
常量对象:
struct connection {
[...]
};
extern const struct connection conn_o;
然后在.c源文件中定义:
[...]
const struct connection conn_o = {
connection_connect, connection_whereami
};
之后,当我尝试将 conn_o
分配给服务器或客户端的静态定义时,我收到一条错误消息,指出初始化元素不是常量。
例如server.c内部的初始化器是这样处理的:
__server server = {
conn_o, server_setup, server_connect
};
是否可以解决此问题,使 conn_o
在 connection.c
内部初始化后保持不变?
谢谢@Lundin 的评论。
我开始了解我对编译语言知之甚少。要隐藏结构的实现细节,您必须使用指向隐藏在 .c 文件中的不透明结构的指针。这允许此结构的编译独立性。要访问不透明结构,您只能使用在头文件中定义的 API 方法(无法引用此类指针来访问它的实例)。这种技术称为 Opaque Pointer、Pimpl Idiom、Bridge Pattern 等
Wikipedia 提供了多种语言的良好实施来源
我现在正在学习 C 中的一些基本多态性。我尝试编写一个常量元素来保存一些方法指针,这些方法指针将被更高级别的结构继承。当我在一个文件中编写所有代码时它工作正常,这是所需的行为:
#include <stdio.h>
#include <string.h>
struct connection {
void (*connect)(struct connection self);
char name[16];
};
void connection_connect(struct connection self) {
printf("Connecting to %s\n", self.name);
}
const struct connection conn = {connection_connect};
typedef struct {
struct connection connection;
void (*setup)(char name[16]);
void (*connect)();
}__server;
__server server;
void server_setup(char name[16]) {
strcpy(server.connection.name, name);
}
void server_connect() {
server.connection.connect(server.connection);
}
__server server = {
conn, server_setup, server_connect
};
typedef struct {
struct connection connection;
void (*setup)(char name[16]);
void (*connect)();
}__client;
__client client;
void client_setup(char name[16]) {
strcpy(client.connection.name, name);
}
void client_connect() {
client.connection.connect(client.connection);
}
__client client = {
conn, client_setup, client_connect
};
int main(void) {
server.setup("Charlie");
client.setup("Delta");
server.connect();
client.connect();
return 0;
}
将所有结构移动到不同的文件时会出现问题。在这种情况下,我被迫 extern
我的连接头文件中的 struct connection
常量对象:
struct connection {
[...]
};
extern const struct connection conn_o;
然后在.c源文件中定义:
[...]
const struct connection conn_o = {
connection_connect, connection_whereami
};
之后,当我尝试将 conn_o
分配给服务器或客户端的静态定义时,我收到一条错误消息,指出初始化元素不是常量。
例如server.c内部的初始化器是这样处理的:
__server server = {
conn_o, server_setup, server_connect
};
是否可以解决此问题,使 conn_o
在 connection.c
内部初始化后保持不变?
谢谢@Lundin 的评论。
我开始了解我对编译语言知之甚少。要隐藏结构的实现细节,您必须使用指向隐藏在 .c 文件中的不透明结构的指针。这允许此结构的编译独立性。要访问不透明结构,您只能使用在头文件中定义的 API 方法(无法引用此类指针来访问它的实例)。这种技术称为 Opaque Pointer、Pimpl Idiom、Bridge Pattern 等
Wikipedia 提供了多种语言的良好实施来源